5886. 如果相邻两个颜色均相同则删除当前颜色(错误代码)
-
开始想到了标记可以删除的,然后轮流A、B直到谁没有能够删除的字符就输。
但是后面考虑了很多奇怪的边界,比如如果删掉了字符之后是否需要重新计算可以删去的字符。如果要考虑删去后的标记,应该用什么容器来储存,因为删去字符串里面的字符,那么标记容器所对应的位置也需要删去对应标记。
但是调试了很久发现有很多奇奇怪怪的BUG,用了太多时间就没有继续下去了。
-
后面看了别人用遍历了一边,直接比较两人可以删除次数。不需要像我这一样考虑这么多情况。
删去字符,因为左右相邻的都是相同的字符才会被标记,比如 AAA 都是 A 那么删去中间字符之后剩下 AA 并没有改变可以删除的情况,所以这里是不需要额外处理的。所以当时没有想到这一点,把代码处理复杂化了。
class Solution
{
public:
bool winnerOfGame(string colors)
{
int n=colors.size();
int cnt1=0,cnt2=0;
int t1=0,t2=0;
for(int i=0; i<n; i++)
{
if(colors[i]=='A')
{
t2=0;
t1++;
if(t1>=3)
{
cnt1++;
}
}
else
{
t1=0;
t2++;
if(t2>=3)
{
cnt2++;
}
}
}
cout<< cnt1<<endl<<cnt2<<endl;
return cnt1>cnt2;
}
};
// 错误代码
#include <bits/stdc++.h>
using namespace std;
// 标记字符是否可删除
vector<bool> isDel;
// 对删除后周围字符重新标记
void process(string colors, int i){
// 左边
if(colors[i-1] == colors[i-2] && colors[i-1] == colors[i])
isDel[i] = true;
if(colors[i+1] == colors[i] && colors[i+1] == colors[i+2])
isDel[i] = true;
}
int main() {
string colors;
cin >> colors;
// 遍历一遍 标记可删除字符
for(int i = 0; i < colors.size() - 1; i++){
// 跳过首尾
if(0 == i || colors.size() - 1 == i)
continue;
// 相邻相等则标记
if(colors[i] == colors[i-1] && colors[i] == colors[i+1])
isDel.push_back(true);
else
isDel.push_back(false);
}
// 1 == Alice -1 == Bob
int AB = 1;
while(1){
bool lose = true;
if(1 == AB){
// 遍历一遍找到对应并且可以删除的字符
for(int i = 0; i < colors.size() - 1; i++){
if('A' == colors[i] && true == isDel[i]){
colors.erase(i, 1);
isDel.erase(begin(isDel) + i);
lose = false;
cout << i << endl;
break;
}
}
// 找不到输了
if(true == lose){
cout << "false";
return false;
}
}
else{
for(int i = 0; i < colors.size() - 1; i++){
if('B' == colors[i] && true == isDel[i]){
colors.erase(i, 1);
isDel.erase(begin(isDel) + i);
lose = false;
cout << i << endl;
break;
}
}
if(true == lose){
cout << "true";
return true;
}
}
// 改变角色
AB *= -1;
}
}