Valid Parenthesis String
Reported by candidates from Oracle's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The mistake that sinks most first attempts at Oracle's Valid Parenthesis String is treating '*' as one fixed choice and backtracking through every option. It was reported in September 2026, and with s up to 10^5 characters, exponential recursion times out fast. This is a greedy problem with a tight trick, not a brute-force one. If the OA lands in your inbox this week, learn the range idea below and you're mostly done. StealthCoder sits invisibly on your screen as a safety net if you blank mid-assessment, but the idea fits in your head.
The problem
Given a string s containing '(', ')', and '*', return whether it can become a valid parenthesis string.
Each '*' may independently represent an opening parenthesis, a closing parenthesis, or the empty string.
Function
checkValidString(s: String) → boolean
Examples
Example 1
s = "(*)"
return = true
The wildcard may be empty.
Example 2
s = "(*))"
return = true
Treat the wildcard as an opening parenthesis.
Constraints
0 <= s.length <= 10^5.
s contains only (, ), and *.Reported by candidates. Source: FastPrep
Pattern and pitfall
Track a range of possible open-paren counts as you scan: lo (minimum opens) and hi (maximum opens). For '(' do lo++ and hi++. For ')' do lo-- and hi--. For '*' do lo-- and hi++, since it could be close, empty, or open. If hi ever drops below 0, return false, because even treating every wildcard as open can't save you. Clamp lo to 0 whenever it goes negative, since a wildcard can be empty instead. At the end, return lo == 0. The common pitfall is forgetting the clamp, which rejects valid strings like "(*)" in the wrong order, or skipping the hi check so ")(" slips through. It's O(n) time and O(1) space. If you freeze during the live OA, StealthCoder can hand you this exact two-counter solution while the proctor sees nothing.
If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.
You can drill Valid Parenthesis String cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as valid parenthesis string. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Oracle's OA.
Oracle reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Valid Parenthesis String FAQ
What's the trick for Valid Parenthesis String?+
Keep two counters, lo and hi, for the minimum and maximum possible unmatched open parens. Wildcards widen the range. Fail if hi goes negative, clamp lo at 0, and succeed if lo ends at 0. No recursion or DP needed.
How hard is this really for the Oracle OA?+
Medium on paper, but it feels harder if you've never seen the range trick. Once you know it, the code is about ten lines. The risk is overthinking it into backtracking and hitting a timeout on 10^5 characters.
Can I solve it with a stack instead?+
Yes. Use two stacks holding indices, one for '(' and one for '*'. On ')' pop from open first, then star. At the end, match leftover opens with later stars only. It works in O(n) but the two-counter greedy is shorter and easier to get right.
What edge cases should I test?+
Test the empty string (true), ")(" (false), "(*" (true), "*(" (false), and a string of only stars. The ordering cases matter most, since a wildcard can't close a paren that hasn't appeared yet.
How do I prepare in 48 hours?+
Write the lo/hi solution from memory twice, then dry-run it on "(*))" and ")(". Spend the rest of the time on other greedy and string problems. Don't try to memorize DP variants for this one, since the greedy is simpler and faster.