给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。
* 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
一个空字符串也被视为有效字符串。
示例 1:
输入: "()"
输出: True
示例 2:
输入: "(*)"
输出: True
示例 3:
输入: "(*))"
输出: True
注意:
字符串大小将在 [1,100] 范围内。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parenthesis-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
设置两个栈,一个栈用来存放左括号,另外一个栈用来存放 *
遇到右括号的时候看看两个栈是不是都是空的,如果是的,那么说明这个右括号前面没有左括号或者 * 直接false返回
如果不是的话,就说明两者至少有一个存在,如果都存在的话优先返回左括号,因为 * 可以用于后续的变换
经过上面的处理右括号一定都被处理完了,因为如果有一个右括号没被处理一定是出错返回了
现在两个栈中仍然存在 元素需要判断,如果左括号栈中有, * 栈中没有 那么false返回
如果*栈中有,左括号没有,那么true返回,因为 * 可以被当作空串
如果两者都有还有以下情况需要判断:
因为左括号的右边必须要有 * ,所以我们存留在 * 栈中的下标需要要大于 左括号的下标,如果不是就false返回,因为 左括号的右边没有可以抵消的 * 了
如果满足上诉条件就要相互出栈(也就是抵消)..直到其中的一个栈中没有元素为止.就是上面讨论的情况之一了
class Solution {
public:
bool checkValidString(string s)
{
stack<int> left,star;
for(int i=0;i<s.size();i++)
{
if( s[i] == '(' )
left.push(i);
else if( s[i] == '*' )
star.push(i);
else
{
//cout<<"??"<<endl;
if(left.empty() && star.empty())
return false;
if(!left.empty())
left.pop();
else
star.pop();
}
}
while(!left.empty() && !star.empty())
{
if( left.top() > star.top() )
{
return false;
}
left.pop();
star.pop();
}
return left.empty();
}
};