intermediate7 min read·Updated October 4, 2026
Generate Parentheses Explained: Tracing n = 3 Valid Combinations
Master Generate Parentheses with a complete walkthrough of n = 3 valid strings. Learn the backtracking mental model, recursion tree, and constraints.
By Learnisim AI·Published October 4, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
- recursion basics
- string manipulation
- depth-first search
Why
Why simple nested brackets break standard combinatorics
Phase 1: The Combinatorial Trap
Imagine you need to generate every possible arrangement of matching parentheses for a given pair count . If you attempt this with a brute-force permutation generator, you quickly run into a wall of structural invalidity. For , there are 6 total characters (3 opening
( and 3 closing )), which yields binary choices or raw permutations depending on how you model the slots. Most of those combinations are completely malformed, such as )()()( or )))(((, where closing brackets appear before they have any matching openers.Without a constrained generation strategy, your code wastes massive CPU cycles filtering out garbage strings after the fact. The core problem of generate parentheses is not just counting characters, but ensuring that at every single index along the string, the number of closing parentheses never exceeds the number of opening ones. We need a systematic way to build strings character by character so that illegal states are pruned before they ever materialize.
Model
The Recursive Tree Model for Generate Parentheses
Phase 2: The Decision Tree Model
When we want to generate all valid strings for pairs of parentheses, we can visualize the process as walking down a decision tree. At every single step of building our string, we have a choice: do we append an open parenthesis
( or a close parenthesis )?However, we cannot make these choices blindly, or we end up with invalid sequences like
)( or (()))(. To make this rigorous, our mental model must track two running integers as state: openUsed (how many ( we have placed so far) and closeUsed (how many ) we have placed so far).Instead of generating all possible bitstrings of length 6 (which is 64 combinations for ) and filtering them later, our recursive model prunes invalid branches instantly. We impose two strict structural guardrails on any path:
1. The Open Guard: We can only add an open parenthesis
2. The Close Guard: We can only add a close parenthesis
( if our current openUsed count is strictly less than . For , we can place at most three ( characters total.2. The Close Guard: We can only add a close parenthesis
) if our current closeUsed count is strictly less than openUsed. This ensures a ) never precedes its matching (.Start: (open=0, close=0, path="")
├── Add '(' -> (open=1, close=0, path="(")
│ ├── Add '(' -> (open=2, close=0, path="((")
│ │ └── ...
│ └── Add ')' -> (open=1, close=1, path="()")
└── Add ')' -> BLOCKED (close >= open)
├── Add '(' -> (open=1, close=0, path="(")
│ ├── Add '(' -> (open=2, close=0, path="((")
│ │ └── ...
│ └── Add ')' -> (open=1, close=1, path="()")
└── Add ')' -> BLOCKED (close >= open)
As we trace down this tree for , every time our path reaches a length of (meaning 3 opens and 3 closes), we have successfully constructed one of our target items, such as
(())(). The model turns a messy combinatorial search into a clean, depth-first traversal of valid states.Worked example
Step-by-Step Trace for n = 3 Parentheses
Phase 3: Working Through the n = 3 Decision Tree
To see our recursive tree model in action, let us trace the execution for . We maintain three variables in our function signature:
openUsed (count of open brackets used so far), closeUsed (count of close brackets used so far), and path (the current string being constructed). When both openUsed and closeUsed equal , our path reaches length 6 and we collect it into our results array.Given
- Target pair count:
- Initial state:
- Initial state:
openUsed = 0, closeUsed = 0, `path =Practice
Predicting the Trace for n = 2 Parentheses
Phase 4: Practice
Now that you have seen how the algorithm builds all 5 valid strings for , it is time to test your mental model on a smaller instance. Consider running the same backtracking function with .
Recall the two core rules established in the recursive tree model:
- You may append an opening parenthesis
- You may append a closing parenthesis
- You may append an opening parenthesis
( if your current openCount < n.- You may append a closing parenthesis
) if your current closeCount < openCount.Take out a piece of paper or open a scratchpad and trace out the exact sequence of states
(open, close, path) starting from (0, 0, "") until you hit the base length of .The Task
1. Write down the complete list of valid strings generated when .
2. How many total leaves (both valid and invalid pruned branches) does the recursion tree visit for ?
3. Verify why a state like
2. How many total leaves (both valid and invalid pruned branches) does the recursion tree visit for ?
3. Verify why a state like
open = 1, close = 2 is immediately pruned by the second rule.Apply
Transferring Parenthesis Backtracking to Related Constraints
Phase 5: Transfer
Now that you have traced how the backtracking state machine builds the 5 valid strings for (from
((())) down to ()()()), you can apply this exact decision-tree pattern to kindred structural generation problems. The core rule we established—only taking branches that maintain structural validity at every step—remains identical when the alphabet or limits change.Consider a variant where you must generate all valid combinations of pairs of mixed brackets, such as
() and [], or a problem counting unique binary search trees with nodes, which follows the exact same Catalan number sequence. In each case, your mental model shifts from simple brute-force loops to managing explicit validity invariants during recursion.When facing a new generation problem, ask yourself three questions derived from our backtracking model:
1. What constitutes a single incremental decision (like adding
()?2.What inequality or state count defines an invalid branch that should be pruned immediately?
3.What defines a complete leaf node where the built string or structure is emitted?
By mapping these questions to your working knowledge of
openUsed and closeUsed, you avoid writing redundant validation checks at the end of every recursion branch.FAQ
What is the exact output for n = 3 in Generate Parentheses?
For n = 3, the algorithm generates 5 valid strings: ["((()))", "(()())", "(())()", "()(())", "()()()"].
Why can't we just use standard combinatorics to generate parentheses?
Simple combinatorics would generate 2^(2n) total permutations of opening and closing brackets, but most of them are invalid because a closing bracket cannot appear before its matching opening bracket.
What are the two core tracking rules in the backtracking mental model?
We track the count of open parentheses used (must be less than n) and close parentheses used (must be strictly less than open count to maintain validity).
What is the time complexity of the Generate Parentheses algorithm?
The time complexity is tied to the nth Catalan number, O(4^n / √n), because we only explore valid branches in the recursion tree.