题目描述:
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。
- 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
一个空字符串也被视为有效字符串。
示例 1:
输入: “()”
输出: True
示例 2:
输入: “(*)”
输出: True
示例 3:
输入: “(*))”
输出: True
注意:
字符串大小将在 [1,100] 范围内。
方法1:双栈
主要思路:
(1)使用双栈,分别存储出现星号和左括号的位置的索引;
(2)若出现的是右括号,则先看存储左括号的栈是否为空,若不为空, 则弹出,若为空,则判断存储星号的栈是否为空,若不为空,则弹出,若也为空,则直接返回false;
(3)当字符串s统计结束后,则比较存储左括号和星号的栈的大小,若存储左括号的较多,则直接返回false,因为此时的星号不能代替足够的右括号;
(4)否则,判断两个栈的栈顶元素的大小,既需要星号的索引在左括号的索引的后面,才能说明匹配成功,然后都弹出,接着比较,否则返回false;
class Solution {
public:
bool checkValidString(string s) {
stack<int> st_left;
stack<int> st_star;
//遍历
for(int i=0;i<s.size();++i){
//若是星号和左括号,则直接压入
if(s[i]=='*'){
st_star.push(i);
}
else if(s[i]=='('){
st_left.push(i);
}//若是右括号
else if(s[i]==')'){
//若左括号非空,则弹出
if(!st_left.empty()){
st_left.pop();
}//若是星号为空,则弹出
else if(!st_star.empty()){
st_star.pop();
}
else{//否则,返回false,说明此时右括号较多
return false;
}
}
}
//若是左括号多与星号,则返回false
if(st_left.size()>st_star.size()){
return false;
}//否则,把星号作为右括号进行判断左括号
while(!st_left.empty()){
if(st_left.top()>st_star.top()){
return false;
}
st_left.pop();
st_star.pop();
}
return true;
}
};