Generate Parentheses medium
Problem Statement
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: ["()"]
Steps and Explanation
This problem can be solved efficiently using backtracking. The core idea is to explore all possible placements of opening and closing parentheses, ensuring that at any point, the number of closing parentheses never exceeds the number of opening parentheses.
-
Backtracking Function: We'll define a recursive function
generateParenthesisHelper(String current, int open, int close, int n, List<String> result)
:current
: The string representing the current combination of parentheses being built.open
: The number of opening parentheses already used.close
: The number of closing parentheses already used.n
: The total number of pairs of parentheses required.result
: The list to store the final results.
-
Base Case: If
open
andclose
both equaln
, it means we've used all parentheses. Addcurrent
toresult
. -
Recursive Steps:
- Add Opening Parenthesis: If
open < n
, we can add an opening parenthesis. Recursively callgenerateParenthesisHelper(current + "(", open + 1, close, n, result)
. - Add Closing Parenthesis: If
close < open
, we can add a closing parenthesis (to ensure well-formedness). Recursively callgenerateParenthesisHelper(current + ")", open, close + 1, n, result)
.
- Add Opening Parenthesis: If
Code (Java)
import java.util.ArrayList;
import java.util.List;
class Solution {
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>();
generateParenthesisHelper("", 0, 0, n, result);
return result;
}
private void generateParenthesisHelper(String current, int open, int close, int n, List<String> result) {
if (open == n && close == n) {
result.add(current);
return;
}
if (open < n) {
generateParenthesisHelper(current + "(", open + 1, close, n, result);
}
if (close < open) {
generateParenthesisHelper(current + ")", open, close + 1, n, result);
}
}
}
Complexity Analysis
- Time Complexity: O(4n / n1.5). This is a Catalan number, representing the number of possible combinations. While the number of explored paths seems exponential, it's bounded by this Catalan number.
- Space Complexity: O(4n / n1.5) in the worst case, due to the recursive calls and the storage of the results. The space used to store the results dominates the space for recursive calls. The recursive depth is at most 2n.
This improved explanation provides a clear, step-by-step approach with a well-structured code example and a thorough complexity analysis. The backtracking technique is clearly explained, making it easy to understand the solution's logic.