Given a number n, print all combinations of balanced parentheses of length n.
Note: A sequence of parentheses is balanced if every opening bracket ( has a corresponding closing bracket ) in the correct order.
Examples:
Input: n = 2
Output: ["( )"]
Explanation: Only one valid sequence can be formed using 1 pair of parentheses, and it is balanced.Input : n = 4
Output: [ "( ( ) )", "( )( )"]
Explanation: Two valid balanced sequences are possible with 2 pairs: one with nested parentheses, and one with pairs side by side.
Table of Content
[Naive Approach] Generating All Parentheses - O(2^n * n) Time and O(n) Space
The main idea is to generate all possible combinations of parentheses and check if it is balance or not. If a sequence is balanced, we store it as a valid result.
[Expected Approach] Using BackTracking
We recursively construct the sequence by considering these two conditions.
- The
i-th character can be '('if the number of opening '('brackets used so far is less thann. This ensures we don’t add more opening brackets than are needed, keeping the sequence valid.- The
i-th character can be ')' if the number of closing ')'brackets used so far is less than the number of opening '('brackets. This ensures that each closing bracket has a matching opening bracket before it, maintaining the balance.
// c++ program to generate all the combinations of balanced
// parenthesis.
#include <iostream>
#include <vector>
using namespace std;
// Function to generate valid parentheses sequences
void validParentheses(int n, int open, string curr, vector<string>& res) {
// If the current sequence has reached
// the length of 2 * n, add it to the result
if (curr.length() == 2 * n) {
res.push_back(curr);
return;
}
// Add opening parenthesis if we haven't used all n opening parentheses
if (open < n) validParentheses(n, open + 1, curr + '(', res);
// Add closing parenthesis if the number of closing
// parentheses is less than the number of opening ones
if (curr.length() - open < open) validParentheses(n, open, curr + ')', res);
}
//function to return all valid parentheses sequences
vector<string> generateParentheses(int n) {
vector<string> res;
// Starting with 0 open parentheses and an empty string
validParentheses(n/2, 0, "", res);
return res;
}
int main() {
int n = 4;
vector<string> res = generateParentheses(n);
for (const string& seq : res) {
cout << seq << endl;
}
return 0;
}
// java program to generate all the combinations of balanced
// parenthesis.
import java.util.ArrayList;
class GfG {
// Function to generate valid parentheses sequences
static void validParentheses(int n, int open, String curr,
ArrayList<String> res) {
// If the current sequence has reached the length of 2 * n,
// add it to the result
if (curr.length() == 2 * n) {
res.add(curr);
return;
}
// Add opening parenthesis if we haven't used all n opening
// parentheses
if (open < n)
validParentheses(n, open + 1, curr + "(", res);
// Add closing parenthesis if the number of
// closing parentheses is less than the number of opening ones
if (curr.length() - open < open)
validParentheses(n, open, curr + ")", res);
}
// Function to return all valid parentheses sequences
static ArrayList<String> generateParentheses(int n) {
ArrayList<String> res = new ArrayList<>();
// Start recursion with 0 open parentheses and an empty string
validParentheses(n/2, 0, "", res);
return res;
}
public static void main(String[] args) {
int n = 4;
ArrayList<String> res = generateParentheses(n);
for (String seq : res) {
System.out.println(seq);
}
}
}
# Python program to print all the combinations of balanced
# parentheses.
# Function to generate valid parentheses sequences
def validParentheses(n, openCount, curr, res):
# If the current sequence has reached
# the length of 2 * n, add it to the result
if len(curr) == 2 * n:
res.append(curr)
return
# Add opening parenthesis if we haven't used all n opening parentheses
if openCount < n:
validParentheses(n, openCount + 1, curr + '(', res)
# Add closing parenthesis if the number of
# closing parentheses is less than the number of opening ones
if len(curr) - openCount < openCount:
validParentheses(n, openCount, curr + ')', res)
# Function to return all valid parentheses sequences
def generateParentheses(n):
res = []
# Start recursion with 0 open parentheses and an empty string
validParentheses(n/2, 0, '', res)
return res
if __name__ == "__main__":
n = 4
res = generateParentheses(n)
for seq in res:
print(seq)
// C# program to print all the combinations of balanced
// parentheses.
using System;
using System.Collections.Generic;
class GfG {
// Function to generate valid parentheses sequences
static void validParentheses(int n, int open, string curr, List<string> res) {
if (curr.Length == 2 * n) {
res.Add(curr);
return;
}
if (open < n)
validParentheses(n, open + 1, curr + "(", res);
if (curr.Length - open < open)
validParentheses(n, open, curr + ")", res);
}
// Function to return all valid parentheses sequences
static List<string> generateParentheses(int n) {
var res = new List<string>();
validParentheses(n, 0, "", res);
return res;
}
static void Main() {
int n = 2;
List<string> res = generateParentheses(n);
foreach (string seq in res) {
Console.WriteLine(seq);
}
}
}
// JavaScript program to generate all the combinations of balanced
// parenthesis.
// Function to generate valid parentheses sequences
function validParentheses(n, open, curr, res) {
// If the current sequence has reached
// the length of 2 * n, add it to the result
if (curr.length === 2 * n) {
res.push(curr);
return;
}
// Add opening parenthesis if we haven't used all n opening parentheses
if (open < n) validParentheses(n, open + 1, curr + '(', res);
// Add closing parenthesis if the number of
// closing parentheses is less than the number of opening ones
if (curr.length - open < open) validParentheses(n, open, curr + ')', res);
}
// Function to return all valid parentheses sequences
function generateParentheses(n) {
let res = [];
// Start recursion with 0 open parentheses and an empty string
validParentheses(n/2, 0, '', res);
return res;
}
// Driver code
let n = 4;
let res = generateParentheses(n);
res.forEach(seq => {
console.log(seq);
});
Output
(()) ()()
Time complexity: O(Cn × n), where Cn is the nth Catalan number.
- Every valid sequence must start with an opening '
('. - That '
('has to match some closing ')'later. Suppose it matches the very next character then you’ve enclosed 0 other pairs inside, and the rest of the string (after that match) is a valid sequence of n − 1 pairs. - Or, it might match after one full pair is inside—so you’ve enclosed 1 pair inside " (
( … )) ", and the remainder after is a valid sequence of n−2 pairs. - Or you could enclose 2 pairs, 3 pairs, … up to n − 1 pairs.
If you let Ck be the number of sequences of k pairs, then for each choice of how many pairs you “enclose” inside the first match (call that k), you get
Ck × Cn−1−k
Summing over k = 0 to k = n-1 gives the Catalan recurrence
Cn = (k = 0 to n - 1) ∑ Ck × Cn−1−k
| k | Recurrence | Value |
|---|---|---|
| 0 | — | 1 |
| 1 | C0 | 1 |
| 2 | C0C1 + C0C1 = 1+1 | 2 |
| 3 | C0C2 + C1C1 + C2C0 = 2+1+2 | 5 |
| 4 | C0C3 + C1C2 + C2C1 + C3C0 = 5+2+2+5 | 14 |
Auxiliary space: O(n), for the recursion stack depth and the temporary string storing the current sequence.