1.题目描述
2.思路
先给出两个错误的思路:
2.1将字符串s的前一半压入栈和后一半做对比。
bool isValid(string s) {
int len=s.length();
if(len==0 || len%2==1)
return false;
int cir=len/2;
stack<char> right;
int i;
for(i=0;i<cir;i++){
right.push(s.back());
s.pop_back();
}
while(!right.empty()){
if((s.back()=='(' && right.top()==')')
||(s.back()=='[' && right.top()==']')
|| (s.back()=='{' && right.top()=='}')){
s.pop_back();
right.pop();
}
else
break;
}
if(right.empty())
return true;
return false;
}
这种方法对非嵌套的括号明显不对。
2.2当字符为左括号时,将对应变量加一,当字符为右括号时,将对应字符减一。
bool isValid(string s) {
int len=s.length();
if(len==0 || len%2==1)
return false;
vector<int> left(3,0);
for(int i=0;i<len;i++){
if(s[i]=='(')
left[0]++;
if(s[i]=='[')
left[1]++;
if(s[i]=='{')
left[2]++;
if(s[i]==')'){
if(left[0]==0)
return false;
left[0]--;
}
if(s[i]==']'){
if(left[1]==0)
return false;
left[1]--;
}
if(s[i]=='}'){
if(left[2]==0)
return false;
left[2]--;
}
}
if(left[0]==0 && left[1]==0 && left[2]==0)
return true;
return false;
}
很明显未考虑好字符的顺序。
2.3最后想出的一种正确的做法
从左到右遍历字符串s,遇到左括号就入栈,遇到右括号就与栈顶的括号做比较,如果匹配就弹出栈顶的括号,如果不匹配就不用继续比较下去了。
bool isValid(string s) {
int len=s.length();
if(len==0)
return true;
if(len%2==1)
return false;
stack<char> left;
bool flag=true;
for(int i=0;i<len;i++){
if(s[i]=='(' || s[i]=='[' || s[i]=='{'){
left.push(s[i]);
flag=false;
}
else{
if(!left.empty() && ((left.top()=='(' && s[i]== ')')
||(left.top()=='[' && s[i]== ']')
||(left.top()=='{' && s[i]== '}')))
left.pop();
else
break;
}
}
if(left.empty() && !flag)
return true;
return false;
}
加上flag这个变量的原因是防止最开始出现的是右括号这种情况,应为此情况下,最后栈left也为空,和完全匹配时最后栈的情况一样,所以要加一个额外的变量以示区分。