题意,问一组字符串能不能组成左右区间闭合的情况,且区间内不能有没有成对的,比如([])可以而( [ )就不行。
思路:
1.一开始想当然的以为只要左括号和右括号相等且遍历过程中右括号数量不能比左括号多就行,但是不能解决 ([ )]的这种情况(false),所以重新找了规律。
2.就拿上面那个特殊情况的分析,我们发现我们只要出现了左括号(这里把开口向右的符号都称为左括号),如果要想让已经之前遍历过的左括号能匹配,就必须把当前的括号“消灭”,也就是找到匹配的。
比如说 ( [ ] ), 遍历到[的时候,我要想把‘(’ 和 ‘)’ 匹配好,首先要把我(前面出现的[先干掉,然后才能轮到( 匹配。
3.有了这个逻辑,我们不难发现,先匹配到的左括号,要留到最后解决,因为要把新遇到的左括号先处理掉,而新进来的为了给原来遍历过的括号机会,那么它就可以遇到一个和它能匹配的,就立马消失,然后把这个匹配的位置交给前一次遍历到的左括号。
4.相信细心的人已经发现了一点规律了,这不就是FILO吗,典型的先进后出,栈的规律。好了,我们把之前的思路套到栈这上面,说遇到一个左括号,入栈,遇到一个左括号,入栈,继续遍历,如果发现当前遍历到了右括号,把栈顶元素抽出来,看看匹不匹配,若匹配,直接栈顶元素pop掉,计数器count++,表示一个可以匹配了,然后栈顶元素交给上一次遍历到的左括号,继续执行上述流程。。。(其实这里有个剪枝的方法就是如果当前右括号不等于栈顶元素,完全可以直接return false 了,因为这里已经有个可以卡住的地方了)。
5.出了循环后,我们看看count是不是等于我们的数组长度一半(数组长度为偶数的时候才要进行上述流程,为奇数的时候比不可能两两匹配完,直接return false),是的话就为真,反之为假。
#include
class Solution {
public:
bool isValid(string s) {
int i, j;
int count=0;
stack <char> Mystack;
int len = s.size();
Mystack.push(1);
for(i=0;i<len;i++)
{
if(s[i]=='('||s[i]=='['||s[i]=='{')
Mystack.push(s[i]);
else if(s[i]-Mystack.top()==1||s[i]-Mystack.top()==2)
{
Mystack.pop();
count++;
continue;
}
else
return false;
}
if(count==len/2&&!(len&1))
return true;
else
return false;
}
};