DSA Notes
Master the balanced parentheses problem — validating matching brackets using a stack, all variants (multiple bracket types, minimum additions to balance, longest valid substring), why stacks are the perfect data structure for bracket matching, and interview patterns.
Problem Definition
A string of brackets is balanced if:
- Every opening bracket has a matching closing bracket
- Brackets close in the correct order (LIFO — last opened, first closed)
Implementation — Validate Brackets
Variant 1 — Minimum Additions to Make Valid
def min_add_to_make_valid(s):
"""
Return minimum number of bracket additions to make s valid.
Count unmatched opens and closes.
"""
open_count = 0 # Unmatched '('
close_count = 0 # Unmatched ')'
for char in s:
if char == '(':
open_count += 1
else: # char == ')'
if open_count > 0:
open_count -= 1 # Matched with an open
else:
close_count += 1 # Unmatched close
return open_count + close_count # Need one addition per unmatched
print(min_add_to_make_valid("())")) # 1
print(min_add_to_make_valid("(((")) # 3
print(min_add_to_make_valid("()")) # 0Variant 2 — Longest Valid Parentheses Substring
Variant 3 — Score of Parentheses
Variant 4 — Generate All Valid Combinations
A related problem: generate all valid bracket combinations of length 2n.
The number of valid combinations for n pairs is the n-th Catalan number: C(n) = (2n choose n) / (n+1). For n=3, C(3) = 5, which matches the output above.
Variant 5 — Remove Invalid Parentheses
Given a string with letters and brackets, remove the minimum number of brackets to make it valid. Return all unique results.
Interview Patterns and Tips
Pattern 1: Stack with Extra Data
Sometimes you need to store more than the bracket itself. Store the index for problems asking about the position of invalid brackets:
Pattern 2: Counter Instead of Stack (Only One Bracket Type)
When the problem only involves ( and ), you can replace the stack with a simple integer counter. This drops space complexity from O(n) to O(1):
def is_valid_simple(s):
"""O(1) space for single bracket type problems."""
balance = 0
for c in s:
if c == '(':
balance += 1
elif c == ')':
balance -= 1
if balance < 0:
return False # More ')' than '(' so far
return balance == 0Pattern 3: Two-Pass for Complex Variants
For minimum removal problems, a forward pass handles unmatched ), and a backward pass handles unmatched (:
Common Edge Cases to Test
Always test your bracket validator against these inputs:
| Input | Expected | Why |
|---|---|---|
"" | Valid | Empty string is valid |
"(" | Invalid | Unclosed bracket |
")" | Invalid | Unmatched close |
"()" | Valid | Single pair |
"([{}])" | Valid | Nested, different types |
"([)]" | Invalid | Wrong nesting order |
"(((" | Invalid | Three unclosed |
"))((" | Invalid | Wrong order overall |
"a(b)c" | Valid | Letters mixed in |
Summary
Balanced parentheses problems are solved with a stack because:
- Opening brackets are pushed (remembered for later matching)
- Closing brackets trigger a pop and comparison with the top
- Stack empty at end = all brackets matched
Variants to know:
- Basic validation: O(n) time, O(n) space
- Minimum additions: O(n) time, O(1) space (count unmatched)
- Longest valid substring: O(n) time, O(n) space (track indices)
- Score: O(n) time, O(n) space (track running sums per level)
- Generate all: O(4^n/√n) time, backtracking
- Remove invalid: O(2^n) time, BFS level by level
The counter-based O(1) space solution works when only one bracket type is involved. For multiple bracket types, a stack is essential.
*Next Lesson: Infix Prefix Postfix*
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Balanced Parentheses — Stack-Based Validation with All Variants.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Data Structures & Algorithms topic.
Search Terms
data-structures-algorithms, data structures & algorithms, data, structures, algorithms, stacks, balanced, parentheses
Related Data Structures & Algorithms Topics