小白刷题时学习的一些解法思路及分析,如果有不对的地方可以在评论区指出或私聊,侵删
一、题目描述
Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第 i 个石子的价值。
Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones 中移除任一石子。
如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。
如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob 将会直接获胜(即便是在 Alice 的回合)。
假设两位玩家均采用 最佳 决策。如果 Alice 获胜,返回 true ;如果 Bob 获胜,返回 false 。
示例 1:
输入:stones = [2,1]
输出:true
解释:游戏进行如下:
- 回合 1:Alice 可以移除任意一个石子。
- 回合 2:Bob 移除剩下的石子。
已移除的石子的值总和为 1 + 2 = 3 且可以被 3 整除。因此,Bob 输,Alice 获胜。
示例 2:
输入:stones = [2]
输出:false
解释:Alice 会移除唯一一个石子,已移除石子的值总和为 2 。
由于所有石子都已移除,且值总和无法被 3 整除,Bob 获胜。
示例 3:
输入:stones = [5,1,2,4,3]
输出:false
解释:Bob 总会获胜。其中一种可能的游戏进行方式如下:
- 回合 1:Alice 可以移除值为 1 的第 2 个石子。已移除石子值总和为 1 。
- 回合 2:Bob 可以移除值为 3 的第 5 个石子。已移除石子值总和为 = 1 + 3 = 4 。
- 回合 3:Alices 可以移除值为 4 的第 4 个石子。已移除石子值总和为 = 1 + 3 + 4 = 8 。
- 回合 4:Bob 可以移除值为 2 的第 3 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 = 10.
- 回合 5:Alice 可以移除值为 5 的第 1 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 + 5 = 15.
Alice 输掉游戏,因为已移除石子值总和(15)可以被 3 整除,Bob 获胜。
提示:
1 <= stones.length <= 105
1 <= stones[i] <= 104
来源:力扣(LeetCode)
链接 https://leetcode-cn.com/problems/stone-game-ix
二、解题方法及代码详解
解题思路:
在该问题中,需要考虑的是去除的数总和关于3的余数,剩余石头种类各自的数量。不妨把取出数总和关于3的余数设为x,将数组中各数对三取余,统计余0,余1,余2各数的数量和,记为cnt0,cnt1,cnt2。在A,B均采取最佳策略的前提下分析规则可知:
- A第一手只能取余1或余2的石头
- 取出余0的石头时,相当于在A与B之间交换了一次先后手顺序,即当余0的石头为偶数个时,对游戏无影响;当余0的石头为奇数个时,游戏中存在一次先后手交换的机会
- 当A第一手取出一颗余1或余2的石头时,如果不考虑余0的石头,取石头的顺序应该是固定的序列如下表
取余数 | 1 | 1 | 2 | 1 | 2 | 1 | … |
---|---|---|---|---|---|---|---|
玩家 | A | B | A | B | A | B | … |
总和余 | 1 | 2 | 1 | 2 | 1 | 2 | … |
或
取余数 | 2 | 2 | 1 | 2 | 1 | 2 | … |
---|---|---|---|---|---|---|---|
玩家 | A | B | A | B | A | B | … |
总和余 | 2 | 1 | 2 | 1 | 2 | 1 | … |
- 观察上表可知,余1和余2的数在对局开始时取掉两个一致的数,之后由cnt1和cnt2的大小决定A,B谁取得胜利。
- 当石头被取完依然没有人输掉游戏时,判A输
此时,可以依据余数为0的数的总和,即cnt0的奇偶来分为两种情况。
-
余数为0的数共有偶数个
1、cnt1为0,A,B都只能取余数为2的数
取余数 | 2 | 2 | 1(2) | 2 | 1 | 2 | … |
---|---|---|---|---|---|---|---|
玩家 | A | B | A(false) | B | A | B | … |
总和余 | 2 | 1 | 0 | 1 | 2 | 1 | … |
此时A一定输掉游戏,cnt2为0时同理。
2、 当cnt1和cnt2同时为0时,A一定输掉游戏
3、当cnt1和cnt2均不为零时,A先手取数,A只需先手取较少的数(看表易得,当A,则B一定会因为取出使得总和与三的余数为0而失败。
-
余数为0的数共有奇数个
此时B在博弈中是占据优势的,因为A第一手不能选择cnt0的石头,故交换先后手的优先权是掌握在B的手中。
1、当余1和余2的数量差不超过2时。
此时B可以通过优先使用cnt0来交换先后手,保证自己取胜。
2、当余1和余2的数量差超过2时。
此时不论B是否优先使用cnt0交换先后手次序,A只要在开局选择数量较多的一方,则一定会取得胜利。
代码如下:
java:
class Solution {
public boolean stoneGameIX(int[] stones) {
int[] cnts=new int[3];for(int i : stones)cnts[i % 3]++;return cnts[0]%2==0 ? !(cnts[1] == 0 || cnts[2] == 0) : (Math.abs(cnts[1]-cnts[2]) > 2);}
}
代码详解:
int[] cnts=new int[3];
这个语句创造了一个新的int型数组大小为3的数组,命名为cnts,未显性赋值则均为0。
for(int i : stones)cnts[i % 3]++;
遍历stones数组中的值赋予i,每次循环给cnts数组中取余的位置加一。该部分完成了对stones数组中余数的统计
return cnts[0]%2==0 ? !(cnts[1] == 0 || cnts[2] == 0) : (Math.abs(cnts[1]-cnts[2]) > 2);
语句中包含一个条件运算符(也叫三元运算符)?:,如A?B:C,若A为TRUE,则执行B语句,反之则执行C语句。
该题解参考自:https://leetcode-cn.com/problems/stone-game-ix/solution/gong-shui-san-xie-fen-qing-kuang-tao-lun-h1oa/
如果你在阅读过程中发现错误或不懂的地方,欢迎在评论去中指出或私聊,感谢阅读。