Valid Parenthesis String
MEDIUMDescription
Given a string s containing only three types of characters: '(', ')' and '*', return true if s is valid.
The following rules define a valid string:
- Any left parenthesis
'('must have a corresponding right parenthesis')'. - Any right parenthesis
')'must have a corresponding left parenthesis'('. - Left parenthesis
'('must go before the corresponding right parenthesis')'. '*'could be treated as a single right parenthesis')'or a single left parenthesis'('or an empty string"".
Example 1:
Input: s = "()" Output: true
Example 2:
Input: s = "(*)" Output: true
Example 3:
Input: s = "(*))" Output: true
Constraints:
1 <= s.length <= 100s[i]is'(',')'or'*'.
Approaches
Checkout 4 different approaches to solve Valid Parenthesis String. Click on different approaches to view the approach and algorithm in detail.
Brute Force using Recursion
This approach explores every possible interpretation of the '' characters. For each '', we recursively try three possibilities: treating it as an opening parenthesis '(', a closing parenthesis ')', or an empty string. This exhaustive search checks if any combination results in a valid parenthesis string.
Algorithm
- Define a recursive function
check(s, index, openCount). indexis the current position in the string, andopenCountis the balance of open parentheses.- Base Case 1: If
openCountbecomes negative, it's an invalid state, returnfalse. - Base Case 2: If
indexreaches the end of the string, the string is valid if and only ifopenCountis 0. - Recursive Step:
- If
s[index]is'(', recurse withcheck(s, index + 1, openCount + 1). - If
s[index]is')', recurse withcheck(s, index + 1, openCount - 1). - If
s[index]is'*', explore all three possibilities by making three separate recursive calls:- Treat
*as'(':check(s, index + 1, openCount + 1). - Treat
*as')':check(s, index + 1, openCount - 1). - Treat
*as empty:check(s, index + 1, openCount).
- Treat
- Return
trueif any of the three branches for*returntrue.
- If
We define a recursive function check(index, open_count) which determines if the substring starting from index is valid, given a current balance of open_count open parentheses.
- The base case for the recursion is when we reach the end of the string (
index == s.length()). The string is valid if and only if theopen_countis zero. - Another base case is if
open_countever becomes negative, which means we have an invalid sequence (e.g., a ')' without a preceding '('). In this case, we prune the search path by returningfalse. - In the recursive step, for the character at the current
index:- If it's '(', we increment
open_countand recurse on the next index. - If it's ')', we decrement
open_countand recurse. - If it's '*', we branch out and make three recursive calls: one for treating it as '(', one for ')', and one for an empty string. If any of these branches return
true, the string is valid.
- If it's '(', we increment
class Solution {
public boolean checkValidString(String s) {
return check(s, 0, 0);
}
private boolean check(String s, int index, int openCount) {
if (openCount < 0) {
return false;
}
if (index == s.length()) {
return openCount == 0;
}
char c = s.charAt(index);
if (c == '(') {
return check(s, index + 1, openCount + 1);
} else if (c == ')') {
return check(s, index + 1, openCount - 1);
} else { // c == '*'
// Try all 3 possibilities for '*'
return check(s, index + 1, openCount + 1) || // as '('
check(s, index + 1, openCount - 1) || // as ')'
check(s, index + 1, openCount); // as empty
}
}
}
Complexity Analysis
Pros and Cons
- Simple to understand and implement the core logic.
- Correctly explores all possibilities.
- Extremely inefficient due to its exponential time complexity.
- Will result in a 'Time Limit Exceeded' error on most platforms for non-trivial inputs.
Code Solutions
Checking out 3 solutions in different languages for Valid Parenthesis String. Click on different languages to view the code.
class Solution {
public
boolean checkValidString(String s) {
int x = 0;
int n = s.length();
for (int i = 0; i < n; ++i) {
if (s.charAt(i) != ')') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
x = 0;
for (int i = n - 1; i >= 0; --i) {
if (s.charAt(i) != '(') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
return true;
}
}
Video Solution
Watch the video walkthrough for Valid Parenthesis String
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.