题目
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
- 任何左括号 ( 必须有相应的右括号 )。
- 任何右括号 ) 必须有相应的左括号 ( 。
- 左括号 ( 必须在对应的右括号之前 )。
- *可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
- 一个空字符串也被视为有效字符串。
注意:字符串大小将在 [1,100] 范围内。
示例1:
输入: “()”
输出: True
示例2:
输入: “(*)”
输出: True
示例3:
输入:"(*))"
输出: True
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parenthesis-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一
使用两个 int 型的栈进行模拟,如果是左括号则当前位数进 stk1 ,如果是星号则当前位数进 stk2 ,如果是右括号则判断在它之前是否有左括号或者星号,优先判断是否有左括号 ,因为星号可能需要换成其他符号。
判断存放左括号的 stk1 是否为空,如果不为空,说明需要给它配对右括号,对 stk2 中的元素进行判断,星号出现的位置需要在左括号之后。
class Solution {
public:
stack<int > stk1, stk2;
bool checkValidString(string s) {
int n = s.size();
for(int i = 0; i < n; i ++ ){
char c = s[i];
if(c == '(') stk1.push(i);
else if(c == ')'){
if(!stk1.empty()) stk1.pop();
else if(!stk2.empty()) stk2.pop();
else return false;
}
else stk2.push(i);
}
while(!stk1.empty()){
while(!stk2.empty() && stk2.top() < stk1.top()) stk2.pop();
if(!stk2.empty()) stk2.pop(), stk1.pop();
else return false;
}
return true;
}
};
解法二
统计左括号最少需要数量 l 跟最多需要数量 r
- 当前字符为 ( :l 和 r 同时加 1
- 当前字符为 ) :l 和 r 同时减 1
- 当前字符为 * :l 减 1 , r 加 1
class Solution {
public:
bool checkValidString(string s) {
int l = 0, r = 0;
for (char c : s) {
if (c == '(') l ++ ; r ++ ;
else if (c == ')') l -- ; r -- ;
else l -- ; r ++ ;
l = max(l, 0);
if (l > r) return false;
}
return l == 0;
}
};