Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
前言
今天的第二题难度为中等,乍一看题目好像很难,还是需要查找最优解的博弈论题目,但其实仔细看下去,会发现很简单,算不上中等题。
每日一题
今天的第二题题目是 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 = "AA"
输出:false
解释:
Alice 先操作。
只有 2 个 'A' 且它们都在字符串的两端,所以她无法执行任何操作。
因此,Bob 获胜,返回 false 。
示例 3:
输入:colors = "ABBBBBBBAAA"
输出:false
解释:
ABBBBBBBAAA -> ABBBBBBBAA
Alice 先操作。
她唯一的选择是删除从右数起第二个 'A' 。
ABBBBBBBAA -> ABBBBBBAA
接下来轮到 Bob 操作。
他有许多选择,他可以选择任何一个 'B' 删除。
然后轮到 Alice 操作,她无法删除任何片段。
所以 Bob 获胜,返回 false 。
提示:
- 1 <= colors.length <= 105
- colors 只包含字母 'A' 和 'B'
题解
滑动窗口
题目其实特别简单,因为题目要求要连续的三个 A 或者连续的三个 B,虽然题目说每次的选择都会是最优解,但是其实无论 Alice 和 Bob 怎么做出选择都不会影响最后的结果
如上图,Bob 在删除 B 的时候最少还会留下两个 B 并不会影响到 Alice 移除 A ,同理,Alice 操作也不会影响到 Bob。
所以其实两个人的操作互不影响,那也就谈不上什么博弈,这道题的难度其实应该是很低的,我们只要去循环字符串,判断分别有多少个 A,B 满足 Alice 和 Bob 的删除条件,然后对比一下两个数的大小,就能够知道谁会胜利了。
/**
* @param {string} colors
* @return {boolean}
*/
var winnerOfGame = function(colors) {
let A = 0
let B = 0
for(let i=0;i<colors.length-2;i++){
if(colors[i]+colors[i+1]+colors[i+2] == 'AAA'){
A++
}
if(colors[i]+colors[i+1]+colors[i+2] == 'BBB'){
B++
}
}
if(A>B){
return true
}
return false
};
优化
上面的执行效率并不是特别的理想,稍微做一下代码的优化。
我们新建一个变量用于存放当前 A 或者 B 出现的次数,当它大于等于 3 的时候,说明接下去每一次出现都是 Alice 或 Bob 能够移出的次数,我们可以用这个数来做一个判断,这样就不用做字符串拼串,能节省很多时间。
/**
* @param {string} colors
* @return {boolean}
*/
var winnerOfGame = function(colors) {
let A = 0;
let B = 0;
let cur = '';
let cnt = 0;
for (let i = 0; i < colors.length; i++) {
const ch = colors[i];
if (ch !== cur) {
cur = ch;
cnt = 1;
} else {
cnt += 1;
if (cnt >= 3) {
if(cur == 'A'){
A++
}
if(cur == 'B'){
B++
}
}
}
}
return A > B;
};