0% completed
Problem Statement
Given a string s
containing multiple occurrences
of characters: '('
, ')'
and '*'
, return true
if s is valid
. Otherwise, return false
.
A string is valid if it follows below rules:
- Any left parenthesis
'('
must be closed by corresponding right parenthesis ')'
. - Any right parenthesis
')'
must have a corresponding left parenthesis'('
. '*'
can be used as a single left parenthesis')'
or a single right parenthesis'('
or an empty string""
.
Examples
-
Example 1:
- Input: s=
"*())"
- Expected Output:
true
- Justification: The asterisk can be treated as an open parenthesis, making the string "(())."
- Input: s=
-
Example 2:
- **Input: s =
"((*()**"
- Expected Output:
true
- **Justification: The first and second asterisks can be treated as close parenthesis, and the third asterisk can be treated as an empty string, resulting in a balanced set of parentheses "(()())."
- **Input: s =
-
Example 3:
- Input: s =
"())*"
- Expected Output:
false
- Justification: There's no way to interpret the asterisk that would balance the extra close parenthesis at the start.
- Input: s =
Solution
This solution employs a smart strategy to determine if a string with parentheses and asterisks is valid. It navigates through each character, adjusting counts to represent possible states of open parentheses. The core idea revolves around maintaining two counters: a low counter (lo) to represent the minimum possible open parentheses, assuming asterisks are used optimally, and a high counter (hi) to represent the maximum possible open parentheses, assuming all asterisks are treated as open parentheses.
This dual-counter approach captures the flexibility of asterisks, which can act as either open or close parentheses or be omitted. By updating these counters based on current character analysis and ensuring our high counter never drops below zero (which would indicate too many closing parentheses), we maintain a balance check. If, by the end of the string, our low counter resets to zero, it signifies that there's at least one valid way to interpret the string as properly balanced, making this method both efficient and effective in handling the problem's inherent ambiguity.
Step-by-step Algorithm
- Initialize two variables,
lo
andhi
, to zero. These will track the lower and upper bounds of the count of open parentheses. - Iterate through each character of the string
s
:- If the character is an open parenthesis
'('
, increment bothlo
andhi
by 1. This is because an open parenthesis definitely increases the number of unclosed parentheses. - If the character is a close parenthesis
')'
, decrement bothlo
andhi
by 1. This reflects closing an open parenthesis. However, sincelo
represents a minimum, it cannot be negative; thus, iflo
drops below 0, reset it to 0. - If the character is an asterisk
'*'
, incrementhi
by 1 (as it could act as an open parenthesis) but decrementlo
by 1 (as it could act as a closing parenthesis). However,lo
is adjusted to a minimum of 0 to avoid negative values. - After processing each character, check if
hi
is less than 0. If true, break the loop as it indicates there are too many closing parentheses, making the string invalid.
- If the character is an open parenthesis
- After iterating through the string, check if
lo
equals 0. Alo
of 0 indicates that there is a valid configuration where all open parentheses can be closed, thus the string is valid.
Algorithm Walkthrough
Given the input "((*()**"
, let's apply the algorithm:
lo = 0
,hi = 0
at the start.- First character
'('
: increment bothlo
andhi
by 1.lo = 1
,hi = 1
.
- Second character
'('
: increment bothlo
andhi
by 1 again.lo = 2
,hi = 2
.
- Third character
'*'
:lo
could represent a closing parenthesis, so decrement by 1 (but not less than 0), andhi
could represent an open parenthesis, so increment by 1.lo = 1
(minimum of 1 and not less),hi = 3
.
- Fourth character
'('
: increment bothlo
andhi
by 1.lo = 2
,hi = 4
.
- Fifth character
')'
: decrement bothlo
andhi
by 1.lo = 1
,hi = 3
.
- Sixth character
'*'
: treat'*'
similarly to the third character; decrementlo
by 1 (to a minimum of 0) and incrementhi
.lo = 0
,hi = 4
.
- Seventh character
'*'
: continue with the same approach for'*'
.lo = 0
,hi = 5
.
After completing the iteration, lo
is 0, which indicates the string "((*()**"
can be valid, assuming asterisks are optimally used either as open parentheses, close parentheses, or not used at all.
Code
Complexity Analysis
- Time Complexity: O(n), where n is the length of the input string. The algorithm iterates through the string once.
- Space Complexity: O(1), as the algorithm uses only a constant amount of extra space.
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible