Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules:
- 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.- An empty string is also valid.
Example 1:
Input: "()"
Output: True
Example 2:
Input: "(*)"
Output: True
Example 3:
Input: "(*))"
Output: True
Note:
- The string size will be in the range [1, 100].
感觉这题比看上去要难,第一感应该是O(n)算法,开始的思路是自左向右遍历消去右括号,保存左括号和符号*的下标。消去利用贪心思想,先消去左括号(从右边的左括号开始消,为了之后更容易匹配*,所以用栈保存遍历到的左括号下标),当左括号消完后,再消符号*(从左边的*开始消,为了之后更容易匹配剩余左括号,所以要用双向队列保存符号*下标)。
消完右括号后,再检查左括号和*是否匹配。时间复杂度O(n),空间复杂度O(n).
public boolean checkValidString(String s) {
Stack<Integer> stack=new Stack<>();//store the index of '('
LinkedList<Integer> queue=new LinkedList<>();//store the index of '*'
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='*') queue.add(i);
else if(s.charAt(i)=='('){
stack.add(i);
}else{
if(stack.size()>0) stack.pop();
else{
if(queue.size()==0) return false;
queue.remove();
}
}
}
int count=0;
while(stack.size()>0){
while(queue.size()>0&&stack.peek()<queue.peekLast()){
queue.removeLast();
count++;
}
stack.pop();
count--;
if(count<0) return false;
}
return true;
}
感觉到应该还有更简洁的解决方案,看了官方参考答案https://leetcode.com/problems/valid-parenthesis-string/solution/。
大致思路是:自左向右遍历时。记录当前最多能匹配多少右括号c1,至少还要匹配多少右括号c2。因为c1的数值对后面的右括号还起作用,要维护这一变量,当某一时刻c1<0时。说明右括号对于左侧过多。c2用于检查左括号,是否对于右侧过多。*号能根据后面右括号的情况而变化,遍历过程中只要c1>=0,就行了。当遍历到一个左括号是,标志着它能用于抵消后面的右括号,也标志着,后面必须要有右括号或*号与其抵消。
时间复杂度O(n),空间复杂度O(1).
感觉这种思路还是较难想到的。。。
public boolean checkValidString(String s) {
int c1=0,c2=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)==')'){
c1--;
c2=Math.max(c2-1,0);
}else if(s.charAt(i)=='('){
c1++;
c2++;
}else{
c1++;
c2=Math.max(c2-1,0);
}
if(c1<0) return false;
}
return c2==0;
}