Valid Parenthesis String
A medium Greedy problem included in Love Babbar 450, Striver A2Z. Below: the roles whose interviews prioritise this topic, and how to practise it.
- Topic
- Greedy
- Sheets
- 2
- Core for
- 3 roles
- Platform
- LeetCode
The problem
Given a string containing only '(', ')' and '*', determine if it is a valid parentheses string. The '*' can be treated as a single '(', a single ')', or an empty string.
Example 1
- Input
- s = "()"
- Output
- true
- Why
- Valid parentheses.
Example 2
- Input
- s = "(*)"
- Output
- true
- Why
- * can be treated as empty string, making "()".
Example 3
- Input
- s = "(*))"
- Output
- true
- Why
- * can be treated as "(", making "(())".
Constraints
- 1 <= s.length <= 100
- s[i] is '(', ')', or '*'
How to think about it
Updated 2026-09-09Tracking a single open paren count fails because each asterisk branches possibilities. However, the valid count of open parentheses always forms a contiguous range [minOpen, maxOpen], so you only need to carry two integers forward.
Approaches, worst first
Recursive backtracking with memoization
time O(n^2) · space O(n^2)
Branch into all three possibilities for every asterisk and memoize on (index, openCount). Guarantees correctness but incurs quadratic time and call stack memory.
Two stacks for indices
time O(n) · space O(n)
Store indices of open brackets and asterisks in separate stacks. Pop open brackets on ')', else pop asterisks. Finally, match remaining open brackets with asterisks that appear strictly to their right.
Greedy range trackingWrite this one
time O(n) · space O(1)
Maintain minOpen and maxOpen. On '(', increment both. On ')', decrement both. On '*', decrement minOpen and increment maxOpen. Clamp minOpen at 0. If maxOpen drops below 0, closing parentheses are unmatchable. String is valid if minOpen ends at 0.
Where people lose marks · 3
- Failing to clamp `minOpen = max(0, minOpen)` treats impossible negative open counts as real options, which mistakenly allows future closing parentheses to balance them.
- Allowing `maxOpen < 0` to pass without early return misses strings with an irrecoverable surplus of closing parentheses early on like `")("`.
- Checking only whether total opens plus stars exceeds closes ignores positional ordering: an asterisk cannot close an open parenthesis that appears after it.
The theory behind it
Greedy — the ground this problem stands on. All Greedy problems
What Greedy is
A greedy algorithm makes the best-looking choice available right now, at every step, without ever looking back or second-guessing its decision. Think of a cashier making change by handing over the largest possible coin first, repeatedly, until the total is reached. Unlike dynamic programming, which saves and compares answers to multiple overlapping paths, a greedy strategy commits to one immediate option and keeps moving forward.
When to reach for it
Reach for greedy when problems ask for minimum jumps, interval scheduling, assigning resources to maximize satisfaction, or finding fractional values. Key signals include sorted orders where greedily taking the next item never hurts future options, or gas station round trips where running balances prove reachability. If you can prove that taking the immediate best choice never leaves you worse off than any alternative, greedy gives the fastest answer.
How the pattern works
Start by sorting the input to bring the most promising candidates to the front. At each position, evaluate your local rule, take the best available piece, and update your running state. The crucial mental step is proving the greedy choice property: demonstrate that picking this immediate winner cannot block a better global solution down the road. If choosing an item now forces you to reconsider past decisions when conditions change later, greedy fails and you must switch to dynamic programming instead.
What each operation costs
| Operation | Time |
|---|---|
| sort elements to enable greedy selection | O(n log n) |
| greedy single-pass scan through sorted input | O(n) |
| greedy choice using a priority queue | O(n log n) |
What usually goes wrong with Greedy
- Applying a greedy choice without proving it yields the global optimum, such as picking the largest coin first for arbitrary denominations where dynamic programming was required.
- Forgetting to sort the input before running the greedy loop, making local decisions on unordered elements that produce invalid answers.
- Picking items based on only one attribute when the optimal decision depends on a ratio or combination of multiple attributes.
Which roles need this problem
Greedy is a core topic for these 3 roles — if you're targeting one of them, this problem is early in your path, not optional.
Secondary for 4 more roles, including Site Reliability Engineer, Search Engineer, Quant Developer.
Track this in your role's order
Pick your target role and all 370 problems — including this one — resequence to what that interview actually asks. Free.
Start freeMore Greedy problems
Problem set and role mapping as of .