Generate Parentheses

MediumBacktracking🧩 BacktrackingLeetCode #22 ↗Updated

Problem

Given n pairs of parentheses, list every string of length 2n made of '(' and ')' that is balanced (every prefix has at least as many opens as closes, and the totals match). Any order is fine.
Inputn = 3Output[((())),(()()),(())(),()(()),()()()]
Inputn = 1Output[()]

1 ≤ n ≤ 8  ·  answer size = n-th Catalan number Cn (C8 = 1430)

Try it yourself

Java
class Solution {
    public List<String> generateParenthesis(int n) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Only two rules matter while building left to right: you may add '(' while open < n, and ')' while close < open. Following them means every leaf is valid — no dead branches, no final check.
PatternBacktracking

Instinct Return ALL combinations, permutations, partitions or placements - or ask if any arrangement works - build a candidate step by step and undo each choice.

Memory hack Choose, explore, un-choose - walk the decision tree and snip a branch the moment it can no longer succeed.

Open the Backtracking guide →

Approaches

Brute ForceGenerate All 22n Strings, Then Validate

Time O(22n · n)Space O(n)

Recursively place either bracket at every one of the 2n positions, then keep a finished string only if a running balance never goes negative and ends at 0. Almost all of the 4n strings are rejected.

Java
public List<String> generateParenthesis(int n) {
    List<String> res = new ArrayList<>();
    generateAll(new char[2 * n], 0, res);
    return res;
}
private void generateAll(char[] cur, int pos, List<String> res) {
    if (pos == cur.length) {
        if (isValid(cur)) res.add(new String(cur));
        return;
    }
    cur[pos] = '(';
    generateAll(cur, pos + 1, res);
    cur[pos] = ')';
    generateAll(cur, pos + 1, res);
}
private boolean isValid(char[] cur) {
    int balance = 0;
    for (char c : cur) {
        balance += c == '(' ? 1 : -1;
        if (balance < 0) return false;
    }
    return balance == 0;
}

Clearly correct, but explores 4n leaves to keep only Cn.

At a glance

LevelApproachTimeSpace
Brute ForceGenerate All 22n Strings, Then ValidateO(22n · n)O(n)
BetterClosure Number (Divide by First Pair)O(4n/√n)O(4n/√n)
OptimalBacktracking with Open/Close CountsO(4n/√n)O(n)
Common pitfalls
  • Allowing ')' when close == open — creates invalid prefixes.
  • Checking only the final balance — ")(" has balance 0 but is invalid.
  • Forgetting to undo the append (deleteCharAt) after recursing.
Interview tips
  • Mention the brute force, then show how the two counting rules prune it.
  • Know the count: the answer size is the Catalan number Cn.
  • Explain why a StringBuilder + undo beats creating a new string per call.
Pattern
Constrained backtracking → build sequences char-by-char and only branch on choices that keep the prefix valid.
My notes saved in this browser