力扣——1003. 检查替换后的词是否有效
1003. 检查替换后的词是否有效
给你一个字符串 s ,请你判断它是否 有效 。
字符串 s 有效 需要满足:假设开始有一个空字符串 t = "" ,你可以执行 任意次 下述操作将 t 转换为 s :
- 将字符串
"abc"插入到t中的任意位置。形式上,t变为tleft + "abc" + tright,其中t == tleft + tright。注意,tleft和tright可能为 空 。
如果字符串 s 有效,则返回 true;否则,返回 false。
示例 1:
输入:s = "aabcbc"
输出:true
解释:
"" -> "abc" -> "aabcbc"
因此,"aabcbc" 有效。
示例 2:
输入:s = "abcabcababcc"
输出:true
解释:
"" -> "abc" -> "abcabc" -> "abcabcabc" -> "abcabcababcc"
因此,"abcabcababcc" 有效。
示例 3:
输入:s = "abccba"
输出:false
解释:执行操作无法得到 "abccba" 。
提示:
1 <= s.length <= 2 * 104s由字母'a'、'b'和'c'组成
问题解析
可以想到,既然是在字符串中插入“abc”,那么最后的字符串中至少会有一个完整的子串是“abc”,因为如果这是插入的最后一个“abc”,那么就不会有别的字符串插入它了。
我们就可以先遍历字符串,把所有完整的“abc”都去掉,把剩下的字符串拼接起来。
然后重头遍历新的字符串,继续去掉“abc”,重复如上操作(就像祖玛游戏一样),如果字符串最后清空了,则说明是个有效的字符串。
但是这样有些麻烦,主要是我们要重复的遍历很多次字符串,这里我们可以用栈来优化。
把遍历到的字符全部入栈,如果栈内至少有三个字符,就看最顶上的三个字符是否能组成“cba”(取出来是倒着的)如果可以,就去掉并继续判断。如果不可以再把它们塞回去。
最后看栈是否为空即可。
AC代码
class Solution {
public:
bool isValid(string s) {
stack<char>sta;
int n=s.size(),l=0;
while(l<n)
{
while(sta.size()>=3)
{
char c=sta.top();
if(c!='c')break;
sta.pop();
char b=sta.top();
if(b!='b')
{
sta.push(c);
break;
}
sta.pop();
char a=sta.top();
if(a!='a')
{
sta.push(b);
sta.push(c);
break;
}
sta.pop();
}
sta.push(s[l++]);
}
while(sta.size()>=3)
{
char c=sta.top();
if(c!='c')break;
sta.pop();
char b=sta.top();
if(b!='b')
{
sta.push(c);
break;
}
sta.pop();
char a=sta.top();
if(a!='a')
{
sta.push(b);
sta.push(c);
break;
}
sta.pop();
}
return sta.empty();
}
};