Last Updated: April 1, 2026
We need to produce every possible string of length 2n made up of ( and ) characters that forms valid (balanced) parentheses. "Valid" means every opening parenthesis has a corresponding closing one, and at no point while reading left to right do we encounter more closing brackets than opening ones.
What makes this different from simply generating all permutations of n opening and n closing brackets? Most of those permutations would be invalid. For instance, )( uses one of each but is not well-formed. The challenge is to enumerate only the valid strings efficiently, without generating and filtering all 2^(2n) possibilities.
The key observation is that we can build these strings character by character. At each position, we decide whether to place ( or ). As long as we track how many opening and closing brackets we have used so far, we can enforce validity as we go: we can place ( if we have not used all n of them, and we can place ) only if the count of closing brackets used is less than the count of opening brackets used. This naturally leads to a backtracking solution.
1 <= n <= 8 → The maximum input is tiny. With n = 8, there are only 1,430 valid combinations (the 8th Catalan number). Even brute-force enumeration of all 2^16 = 65,536 binary strings would be fast.The most straightforward approach is to generate every possible string of length 2n using the characters ( and ), then keep only the ones that are valid. Each position in the string has two choices, so there are 2^(2n) total strings. We check each one by scanning left to right and tracking the balance (increment for (, decrement for )). If the balance never goes negative and ends at zero, the string is valid.
This is conceptually simple but wasteful. For n = 8, we generate 65,536 strings but only 1,430 are valid. That is about 2% efficiency. Still, with n capped at 8, it runs fast enough.
( and 1 maps to ).(, subtract 1 for ). If balance goes negative at any point, the string is invalid. If balance is zero at the end, it is valid.We generate every possible string including the vast majority that are invalid. What if we could check validity as we build the string and stop going down a path the moment it becomes impossible to form a valid result?
Instead of generating everything and filtering, we build the string one character at a time and make smart choices at each step. The key insight is that we only need two counters: open (how many ( we have placed) and close (how many ) we have placed). At any point during construction:
( if open < n (we still have opening brackets left to use).) if close < open (we have unmatched opening brackets that need closing).These two simple rules guarantee that every string we complete is valid. We never explore a dead-end path because we never place a character that would make the string invalid. This is classic backtracking: make a choice, recurse, then undo the choice and try the next option.
The beauty of this approach is that it generates exactly the Catalan number C(n) of valid strings, with no wasted work on invalid ones.
The two rules (open < n and close < open) are both necessary and sufficient for validity. The first ensures we do not use more than n opening brackets. The second ensures we never have more closing brackets than opening ones at any prefix, which is exactly the definition of a balanced parentheses prefix. Since we only add to the result when the string reaches length 2n, and at that point open == close == n is guaranteed by the branching logic, every result string is valid.
This is a textbook example of how backtracking can eliminate invalid states early, turning an exponential search space into one that only visits valid states.
open and close counters at 0.open < n, append ( and recurse with open + 1.close < open, append ) and recurse with close + 1.This approach is already optimal for generating all valid strings. But there is an alternative that reveals a beautiful mathematical structure: every valid string can be decomposed as ( + inner + ) + outer, based on where the first ( finds its matching ).
There is an elegant mathematical structure behind valid parentheses. Consider any valid string with n pairs. The first character must be (. Somewhere later in the string, there is a ) that matches this first (. Let's say the matching ) is at index 2k + 1 (0-indexed). Then the string looks like:
( + [valid string with k pairs] + ) + [valid string with n-1-k pairs]
The part inside the first matched pair is a valid string of k pairs (for k from 0 to n-1), and the part after is a valid string of the remaining n-1-k pairs. This is called the "closure number" decomposition.
By iterating k from 0 to n-1 and recursively generating the strings for k pairs and n-1-k pairs, we can build all valid strings for n pairs. This is essentially the recursive definition of the Catalan numbers in action.
Every valid parentheses string has a unique decomposition based on where the first ( finds its matching ). If the matching ) is at position 2k+1, there are exactly k pairs inside and n-1-k pairs outside. By iterating over all possible values of k, we cover every possible structure. The recursive calls generate all valid strings for the sub-problems, and the nested loops combine them in all possible ways.
This directly mirrors the Catalan number recurrence: C(n) = C(0)C(n-1) + C(1)C(n-2) + ... + C(n-1)*C(0). Each term corresponds to one value of k, and the product of Catalan numbers counts the combinations of inner and outer strings.
"".a. Recursively generate all valid strings of k pairs (these go inside the first matched pair).
b. Recursively generate all valid strings of n-1-k pairs (these go after the first matched pair).
c. For each combination of inner and outer strings, create "(" + inner + ")" + outer and add it to the result.