Problem Statement:
Given a string s
containing only '('
, ')'
, and '*'
, return true
if the string is valid.
A string is valid if:
- Every
'('
has a corresponding')'
- Every
')'
has a corresponding'('
'*'
can be treated as'('
,')'
, or an empty string- The parentheses must be balanced and in correct order
Examples:
Example 1:
Input: s = "()" Output: true
Example 2:
Input: s = "(*)" Output: true
Example 3:
Input: s = "(*))" Output: true
Example 4:
Input: s = "(*()(()))((*" Output: false
The challenge is that '*'
can be anything:
'('
')'
''
(empty string)
This means we need to consider multiple possible interpretations.
Greedy Two-Pointer Method (Optimized O(n) time)
This is the optimal and accepted approach, which uses greedy logic and two counters:
low
: Minimum number of open brackets'('
possible at a pointhigh
: Maximum number of open brackets'('
possible at a point
We scan the string left to right:
Character | Effect on low | Effect on high |
---|---|---|
'(' | low++ | high++ |
')' | low-- (if > 0) | high-- |
'*' | low-- or low stays | high++ |
At any point:
- If
high < 0
→ too many')'
, returnfalse
- If
low < 0
→ reset to 0 (because*
can be empty or'('
)
Java Code:
public class ValidParenthesisString { public boolean checkValidString(String s) { int low = 0; // min open brackets int high = 0; // max open brackets for (char ch : s.toCharArray()) { if (ch == '(') { low++; high++; } else if (ch == ')') { if (low > 0) low--; high--; } else if (ch == '*') { if (low > 0) low--; // treat '*' as ')' high++; // treat '*' as '(' } // If too many ')' if (high < 0) return false; } // If all open brackets are matched return low == 0; } // Testing public static void main(String[] args) { ValidParenthesisString vps = new ValidParenthesisString(); System.out.println(vps.checkValidString("(*)")); // true System.out.println(vps.checkValidString("(*))")); // true System.out.println(vps.checkValidString("((*)")); // true System.out.println(vps.checkValidString("(*(()")); // false } }
Dry Run
Let’s take s = "(*))"
Initialize: low = 0
, high = 0
Char | Action | low | high |
---|---|---|---|
( | +1 open | 1 | 1 |
* | -1 or +1 or 0 | 0 | 2 |
) | -1 close | 0 | 1 |
) | -1 close | 0 | 0 |
All open brackets are closed → Valid → return true