Problem Statement
Given an integer n
, generate all combinations of well-formed parentheses that consist of exactly n
pairs of opening and closing parentheses. The formed length would be 2*n
.
LeetCode
https://leetcode.com/problems/generate-parentheses/description/
Constraints
1 <= n <= 8
- The constraint
1 <= n <= 8
typically indicates that:n
is small — it's a number between 1 and 8.- You can use algorithms with high time complexity, such as brute-force, backtracking, or recursion with permutations, because the total number of possibilities will be small.
Examples
Example 1:
Input: n = 3
Output:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
Example 2:
Input: n = 2
Output: [
"(())",
"()()"
]
Example 3:
Input: n = 1
Output: [
"()"
]
Constraints for Well-Formed Parentheses:
To be considered a well-formed (valid) parentheses combination:
- The number of opening parentheses
'('
should always be equal to the number of closing parentheses')'
. - At any point in the combination, the number of closing parentheses
')'
should not exceed the number of opening parentheses'('
. If it does, the combination is invalid.
Different Approaches
1️⃣ Recursion
The idea is to build the parentheses string recursively, ensuring that at any point:
- We can add an opening parenthesis
(
if we haven’t used alln
opening parentheses yet. - We can add a closing parenthesis
)
only if the number of closing parentheses is less than the number of opening parentheses used so far.
The recursive approach is a classic depth-first search (DFS) where we try to build valid parentheses strings by adding an open (
or a close )
at each step, ensuring that:
- We can only add an open
(
if we have fewer thann
open parentheses. - We can only add a close
)
if the number of close parentheses is less than the number of open parentheses.
Recursive Algorithm:
- Start with an empty string and
n
as the input for the number of pairs of parentheses. - At each step, you have two options:
- Add an open
(
parenthesis if you haven’t used alln
open parentheses. - Add a close
)
parenthesis if the number of close parentheses is less than the number of open parentheses.
- Add an open
- When the string reaches a length of
2 * n
(which means all open and close parentheses have been used), add it to the result.
Recursion Tree:


Code:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void generateParenthesisRec(int open, int close, string current, vector<string>& result) {
// Base case: If the current string is valid and complete
if (open == 0 && close == 0) {
result.push_back(current);
return;
}
// Recursive case: Try to add open and close parentheses
if (open > 0) {
generateParenthesisRec(open - 1, close, current + "(", result);
}
if (close > open) {
generateParenthesisRec(open, close - 1, current + ")", result);
}
}
vector<string> generateParenthesis(int n) {
vector<string> result;
generateParenthesisRec(n, n, "", result);
return result;
}
int main() {
int n = 3;
vector<string> result = generateParenthesis(n);
for (const string &s : result) {
cout << s << endl;
}
return 0;
}
Visualization of the Recursive Process for n = 3
:
We start with n = 3
pairs of parentheses. At each step, we can either add an open parenthesis (
if open > 0
or a close parenthesis )
if close > open
.
Here’s a recursive tree that illustrates the process:
""
/ \
"(" ""
/ \ \
"((" "()" ""
/ \ / \ \
"(((" "(()" "()(" "()" ""
/ \ / \ / \ \ \
"((())" "(()()" "()()" "()" "()(" ""
| | | | | |
"((()))" "(()())" "(())()" "()(())" "()()()"
Detailed Walkthrough:
At each node in the recursion tree:
- Open parentheses (
(
) are added if there are still open parentheses left. - Close parentheses (
)
) are added if the number of close parentheses is less than the number of open parentheses.
Step-by-Step Breakdown:
- Start with the empty string
""
:- Add an open parenthesis
(
. - Now you have
open = 2
andclose = 3
.
- Add an open parenthesis
- At
"("
:- You still have
open = 2
andclose = 3
remaining. - Add another open parenthesis
(
→"(("
. - Now you have
open = 1
andclose = 3
.
- You still have
- At
"(("
:- Add another open parenthesis
(
→"((("
. - Now you have
open = 0
andclose = 3
.
- Add another open parenthesis
- At
"((("
:- No more open parentheses to add (
open = 0
). - Add a close parenthesis
)
→"((()"
. - Now you have
open = 0
andclose = 2
.
- No more open parentheses to add (
- At
"((()"
:- Add another close parenthesis
)
→"((())"
. - Now you have
open = 0
andclose = 1
.
- Add another close parenthesis
- At
"((())"
:- Add another close parenthesis
)
→"((()))"
. - Now you have
open = 0
andclose = 0
. - Since both
open
andclose
are 0, the string"((()))"
is a valid solution.
- Add another close parenthesis
- Backtracking:
- Backtrack to previous nodes and try other combinations, like adding close parentheses earlier:
"(()()"
,"()(())"
,"()()()"
, etc.
- Backtrack to previous nodes and try other combinations, like adding close parentheses earlier:
Complexity Analysis:
- Time Complexity:
- The time complexity is proportional to the
Catalan number
Cn
, which is approximatelyO(4^n / under-root of n)
.
- The time complexity is proportional to the
- Space Complexity:
- The space complexity is
O(n)
for the recursion stack since each recursive call adds one level to the stack (up ton
levels deep). - The result takes up
O(4^n / under-root of n)
space to store all valid combinations.
- The space complexity is