主要思路
1.字符串s是由不断地给字符串t(初始为空)插入字符串"abc"构成的(插入位置随机),所以我们反向考虑,不断在字符串s中去除连续的"abc",如果最后为空,说明就是有效的。
2. 具体做法就是遍历字符串s,每遇到一段连续的"abc"字段就把他们删除,然后对重新组成的字符串在执行上述操作。比如字符串s = “aabcabcbc”,我们先删除第一段连续的abc,即s[1]至s[3],删除后s成了"aabcbc",在删除连续的abc,剩余的字符串成了abc,最后删除,字符串成了空,说明就是有效的。
3. 代码实现:始终维护一个栈,我们直接遍历字符串s,如果当前元素是字符a,则直接入栈,如果是字符b,则检查栈顶元素是否为a,栈顶是a的话将字符b入栈(因为a和b肯定是连着的),如果当前元素是c,则检查栈顶元素是否是b,如果是b说明找到了一段连续的abc字段,我们将b和a出栈,若不满足上述情况则直接返回false,肯定是无效的,重复上述操作。
最后如果栈为空则说明是有效的。
其实总结就一句话,不断将字符串s中连续的abc删除,如果最后s成为空了,即删光了(想想s是怎么由t+abc构成的,反向拆解),说明就是有效的,否则就是非法的。
class Solution {
public:
bool isValid(string s) {
if(s.length()<3 || s[0]!='a')return false;//有效的字符串s第一个字符肯定是a,因为不管每次将abc插入到哪里,头部肯定是a
int len = s.length();
stack<char> stk;
for(int i = 0;i<len;++i) {
if(s[i]=='a')stk.push('a');
else {
if(s[i]=='b'&&!stk.empty()&&stk.top()=='a') {
stk.push('b');
}
else if(s[i]=='c'&&!stk.empty()&&stk.top()=='b') {
stk.pop();
stk.pop();
}
else {
return false;
}
}
}
return stk.empty()?true:false;
}
};