Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
每日刷题第72天 2021.03.22
2038. 如果相邻两个颜色均相同则删除当前颜色
- leetcode原题链接:leetcode-cn.com/problems/re…
- 难度:中等
- 方法:脑筋急转弯
题目描述
- 总共有 n 个颜色片段排成一列,每个颜色片段要么是 'A' 要么是 'B' 。给你一个长度为 n 的字符串 colors ,其中 colors[i] 表示第 i 个颜色片段的颜色。
- Alice 和 Bob 在玩一个游戏,他们 轮流 从这个字符串中删除颜色。Alice 先手 。
- 如果一个颜色片段为 'A' 且 相邻两个颜色 都是颜色 'A' ,那么 Alice 可以删除该颜色片段。Alice 不可以 删除任何颜色 'B' 片段。
- 如果一个颜色片段为 'B' 且 相邻两个颜色 都是颜色 'B' ,那么 Bob 可以删除该颜色片段。Bob 不可以 删除任何颜色 'A' 片段。
- Alice 和 Bob 不能 从字符串两端删除颜色片段。
- 如果其中一人无法继续操作,则该玩家 输 掉游戏且另一玩家 获胜 。
- 假设 Alice 和 Bob 都采用最优策略,如果 Alice 获胜,请返回 true,否则 Bob 获胜,返回 false。
示例
- 示例1
输入:colors = "AAABABB"
输出:true
解释:
AAABABB -> AABABB
Alice 先操作。
她删除从左数第二个 'A' ,这也是唯一一个相邻颜色片段都是 'A' 的 'A' 。
现在轮到 Bob 操作。
Bob 无法执行任何操作,因为没有相邻位置都是 'B' 的颜色片段 'B' 。
因此,Alice 获胜,返回 true 。
- 示例2
输入:colors = "ABBBBBBBAAA"
输出:false
解释:
ABBBBBBBAAA -> ABBBBBBBAA
Alice 先操作。
她唯一的选择是删除从右数起第二个 'A' 。
ABBBBBBBAA -> ABBBBBBAA
接下来轮到 Bob 操作。
他有许多选择,他可以选择任何一个 'B' 删除。
然后轮到 Alice 操作,她无法删除任何片段。
所以 Bob 获胜,返回 false 。
解题思路
最开始的思路
- 根据题意可知:只要有连续的三个相同的字母,就可以消掉一个。题中还说,不能消除掉两端的字母,但是其实这并不影响,三个相同的字母中,不论删除哪一个都只能计算一次有效。
- 因此:遍历整个数组一遍,分别计算出
A\B符合的次数,最终将两次数进行比较A先走- 当
A > B时,一定是A赢 - 当
A <= B时,一定是B赢
- 那么分析到这里,后面就需要考虑:如何来统计
A\B分别的有效次数- 双指针:左指针和右指针,左指针固定字母开头的位置,右指针往后一直查找到所有的连续的相同字母。当出现第一个不相同的字母的时候,就需要将前面已经找到的字母的连续次数处理,取
0和max - 2- 注意:一定要初始化每次统计连续字母的变量为
0 - 当然直接使用
for循环也可以,直接每次遍历每次取结果,遇到A就要对前面连续的B进行操作,反之亦然。
- 注意:一定要初始化每次统计连续字母的变量为
- 截取字符串:
for循环,判断当前colors[i]是A还是B,使用字符串截取的方法,截取从当前位置开始,长度为3的字符串,判断其是否符合要求,是否能算作有效次数。
- 双指针:左指针和右指针,左指针固定字母开头的位置,右指针往后一直查找到所有的连续的相同字母。当出现第一个不相同的字母的时候,就需要将前面已经找到的字母的连续次数处理,取
AC代码
var winnerOfGame = function(colors) {
let len = colors.length,numA = 0,numB = 0;
let l = 0,r = 0,serialA = 0,serialB = 0;
while(l < len) {
if(colors[l] == 'A'){
r = l;
while(colors[r] == 'A' && r < len){
serialA++;
r++;
}
l = r;
numA += Math.max(serialA - 2, 0);
serialA = 0;
}else if(colors[l] == 'B'){
r = l;
while(colors[r] == 'B' && r < len) {
serialB++;
r++;
}
l = r;
// console.log(serialB)
numB += Math.max(serialB - 2, 0);
serialB = 0;
}
}
// console.log(numA,numB)
if(numA > numB){
return true;
}else {
return false;
}
};
总结
- 简单题多看几种解法,拓展思维。