Skip to content

Implement Parentheses Generator #5096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 5, 2024
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [MazeRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java)
* [MColoring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MColoring.java)
* [NQueens](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/NQueens.java)
* [ParenthesesGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java)
* [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java)
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java)
* [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.thealgorithms.backtracking;

import java.util.ArrayList;
import java.util.List;

/**
* This class generates all valid combinations of parentheses for a given number of pairs using backtracking.
*/
public final class ParenthesesGenerator {
private ParenthesesGenerator() {
}

/**
* Generates all valid combinations of parentheses for a given number of pairs.
*
* @param n The number of pairs of parentheses.
* @return A list of strings representing valid combinations of parentheses.
* @throws IllegalArgumentException if n is less than 0.
*/
public static List<String> generateParentheses(final int n) {
if (n < 0) {
throw new IllegalArgumentException("The number of pairs of parentheses cannot be nagative");
}
List<String> result = new ArrayList<>();
generateParenthesesHelper(result, "", 0, 0, n);
return result;
}

/**
* Helper function for generating all valid combinations of parentheses recursively.
*
* @param result The list to store valid combinations.
* @param current The current combination being formed.
* @param open The number of open parentheses.
* @param close The number of closed parentheses.
* @param n The total number of pairs of parentheses.
*/
private static void generateParenthesesHelper(List<String> result, final String current, final int open, final int close, final int n) {
if (current.length() == n * 2) {
result.add(current);
return;
}
if (open < n) {
generateParenthesesHelper(result, current + "(", open + 1, close, n);
}
if (close < open) {
generateParenthesesHelper(result, current + ")", open, close + 1, n);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.thealgorithms.backtracking;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class ParenthesesGeneratorTest {
@ParameterizedTest
@MethodSource("regularInputStream")
void regularInputTests(int input, List<String> expected) {
assertEquals(expected, ParenthesesGenerator.generateParentheses(input));
}

@ParameterizedTest
@MethodSource("negativeInputStream")
void throwsForNegativeInputTests(int input) {
assertThrows(IllegalArgumentException.class, () -> ParenthesesGenerator.generateParentheses(input));
}

private static Stream<Arguments> regularInputStream() {
return Stream.of(Arguments.of(0, List.of("")), Arguments.of(1, List.of("()")), Arguments.of(2, List.of("(())", "()()")), Arguments.of(3, List.of("((()))", "(()())", "(())()", "()(())", "()()()")),
Arguments.of(4, List.of("(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()")));
}

private static Stream<Arguments> negativeInputStream() {
return Stream.of(Arguments.of(-1), Arguments.of(-5), Arguments.of(-10));
}
}