Medium, Dynamic Programming
Given n pairs of parentheses, write a function
to generate all combinations of well-formed parentheses.
Example 1:
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Example 2:
Input: n = 1
Output: ["()"]
Constraints:
- 1
<= n <= 8
Approach:
-
Backtracking:
- Start with an empty string.
- Maintain counts for the number of open and close parentheses used.
- Only add:
- An open parenthesis if the count of open parentheses is less than .
- A close parenthesis if the count of close parentheses is less than the count of open parentheses (to ensure the string remains valid).
- Once both open and close parentheses are used times, add the string to the result.
-
Algorithm:
- Use a helper function
Backtrack
that takes the current string, counts of open and close parentheses, and as arguments. - Recursively explore all valid combinations.
- Stop the recursion when both open and close counts reach .
- Use a helper function
Implementation:
public class Solution {
public IList<string> GenerateParenthesis(int n) {
List<string> result = new List<string>();
Backtrack(result, "", 0, 0, n);
return result;
}
private void Backtrack(List<string> result, string current, int open, int close, int max) {
// If the current string is complete, add it to the result
if (current.Length == max * 2) {
result.Add(current);
return;
}
// Add an open parenthesis if the count is less than max
if (open < max) {
Backtrack(result, current + "(", open + 1, close, max);
}
// Add a close parenthesis if it doesn't exceed the number of open ones
if (close < open) {
Backtrack(result, current + ")", open, close + 1, max);
}
}
}
Explanation of Code:
-
Base Case:
- When the length of the current string is , it is a valid combination and added to the result list.
-
Recursive Case:
- Add
(
if the number of open parentheses used is less than . - Add
)
if the number of close parentheses is less than the number of open parentheses.
- Add
-
Termination:
- The recursion stops when all valid combinations are generated.
Complexity Analysis:
-
Time Complexity:
- Each valid combination is of length .
- There are (Catalan numbers) valid combinations.
- Hence, the complexity is approximately .
-
Space Complexity:
- The recursion stack can go as deep as , so .
Example Outputs:
Example 1:
- Input:
n = 3
- Output:
["((()))", "(()())", "(())()", "()(())", "()()()"]
Example 2:
- Input:
n = 1
- Output:
["()"]
This implementation generates all well-formed parentheses combinations efficiently while ensuring correctness through backtracking.