Basic Recursion, Check Balanced Parenthesis
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Checking whether parentheses are balanced is a classic algorithm exercise because it forces you to define correctness precisely. The recursive version is especially useful for learning how state moves through a problem one character at a time, even though an iterative stack is often the production-friendly solution.
For strings containing only ( and ), the rule is simple: the running balance must never drop below zero, and the final balance must be exactly zero. Recursion works well because those two conditions can be checked incrementally.
Write the Recursive Version Around a Running Count
The core idea is to walk through the string with two pieces of state:
- the current index
- the number of unmatched opening parentheses seen so far
Here is a direct recursive implementation in Python:
This solution is small, but it captures the entire problem. Every opening parenthesis increments the count. Every closing parenthesis decrements it. Any negative count means the string became invalid before it even ended.
Understand Why the Base Cases Are Correct
The recursive logic depends on two base cases.
First, if open_count ever becomes negative, the string is already invalid because a closing parenthesis appeared without a matching earlier opening parenthesis.
Second, when the recursion reaches the end of the string, the expression is balanced only if open_count == 0. A positive count at the end means there are unmatched opening parentheses left over.
Those rules explain why strings such as )( are invalid even though they contain the same number of opening and closing characters overall. The failure is in the order, not just the totals.
Compare It with a Stack-Based Solution
For this one-type problem, the counter is enough. Once multiple bracket types are introduced, a simple count no longer captures the ordering constraints correctly. At that point a stack is the better abstraction.
This handles (), [], and {} because it remembers the exact opening symbols and their nesting order, which a single counter cannot do.
Know When Recursion Stops Being Practical
The recursive approach is excellent for teaching and interviews because it makes the logic explicit. In production, though, recursion depth matters. Very long inputs can hit recursion limits in languages such as Python.
That is why an iterative solution is often preferred for real parsers or large inputs. The algorithmic idea is the same, but iteration avoids the call-stack limit and is usually easier to optimize.
Still, recursion is valuable here because it trains the habit of expressing a problem in terms of state transitions and base cases. That habit generalizes well to tree traversal, backtracking, and divide-and-conquer problems.
Common Pitfalls
The biggest mistake is checking only whether the final count is zero. That misses cases like )(, where the total count balances but the order is invalid.
Another common mistake is using the one-counter solution for multiple bracket types. The moment bracket type and nesting order both matter, you need a stack or an equivalent structure.
It is also easy to forget what should happen with non-parenthesis characters. Some versions of the problem ignore them, while others reject them. The implementation should match the chosen rule explicitly.
Finally, recursive code can fail on very long inputs because of recursion depth, even when the logic is otherwise correct.
Summary
- A balanced parenthesis string never goes negative and ends at zero.
- A recursive helper can track the current index and open count cleanly.
- Early failure on negative balance is essential for correctness.
- Use a stack instead of a counter when multiple bracket types are involved.
- Recursion is a good teaching tool here, even if iteration is often more practical.

