Generate Parentheses
Problem Statement
Given an integer n, generate all valid combinations of n pairs of parentheses. A combination is valid if every opening parenthesis '(' has a matching closing parenthesis ')', and the sequence is well-formed (no closing before opening). This medium-level problem uses recursion and backtracking to build balanced strings—think of it as crafting perfectly nested expressions!
Example
Input: n = 3
Output: ["((()))", "(()())", "(())()", "()(())", "()()()"] (all 5 valid ways for 3 pairs)
Input: n = 1
Output: ["()"] (only one way for 1 pair)
Code
Java
Python
JavaScript
public class Solution { public ListgenerateParenthesis(int n) { List result = new ArrayList<>(); backtrack(result, "", 0, 0, n); return result; } private void backtrack(List result, String current, int open, int close, int max) { if (current.length() == max * 2) { result.add(current); return; } if (open < max) { backtrack(result, current + "(", open + 1, close, max); } if (close < open) { backtrack(result, current + ")", open, close + 1, max); } } }
def generate_parenthesis(n): def backtrack(current, open_count, close_count): if len(current) == n * 2: result.append(current) return if open_count < n: backtrack(current + "(", open_count + 1, close_count) if close_count < open_count: backtrack(current + ")", open_count, close_count + 1) result = [] backtrack("", 0, 0) return result # Example usage print(generate_parenthesis(3)) # ["((()))", "(()())", "(())()", "()(())", "()()()"] print(generate_parenthesis(1)) # ["()"]
function generateParenthesis(n) { function backtrack(current, open, close) { if (current.length === n * 2) { result.push(current); return; } if (open < n) { backtrack(current + "(", open + 1, close); } if (close < open) { backtrack(current + ")", open, close + 1); } } let result = []; backtrack("", 0, 0); return result; } // Example usage console.log(generateParenthesis(3)); // ["((()))", "(()())", "(())()", "()(())", "()()()"] console.log(generateParenthesis(1)); // ["()"]
Explanation
- Base Case: When string length equals 2n (n pairs), add it to the result.
- Choices: Add an opening '(' if fewer than n are used, or a closing ')' if fewer than open.
- Backtracking: Build the string incrementally, exploring all valid paths.
- Flow Example (n=2): "" → "(" → "((" → "(()" → "(())"; backtrack to "()" → "()(" → "()()".
- Validity: Ensures well-formedness by only closing when there’s an unmatched opening.
Note
Time complexity is O(4^n / √n), the nth Catalan number, representing valid combinations. Space complexity is O(n) for the call stack plus O(4^n / √n) for the result. It’s a elegant dance of balance!