2038. 如果相邻两个颜色均相同则删除当前颜色(思维题)

173 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第72天 2021.03.22

2038. 如果相邻两个颜色均相同则删除当前颜色

题目描述

  • 总共有 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分别的有效次数
    • 双指针:左指针和右指针,左指针固定字母开头的位置,右指针往后一直查找到所有的连续的相同字母。当出现第一个不相同的字母的时候,就需要将前面已经找到的字母的连续次数处理,取0max - 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;
  }
};

总结

  • 简单题多看几种解法,拓展思维。