leetcode刷题(题号:2029)

小白刷题时学习的一些解法思路及分析,如果有不对的地方可以在评论区指出或私聊,侵删

一、题目描述

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的石头,取石头的顺序应该是固定的序列如下表
取余数112121
玩家ABABAB
总和余121212

取余数221212
玩家ABABAB
总和余212121
  • 观察上表可知,余1和余2的数在对局开始时取掉两个一致的数,之后由cnt1和cnt2的大小决定A,B谁取得胜利。
  • 当石头被取完依然没有人输掉游戏时,判A输

此时,可以依据余数为0的数的总和,即cnt0的奇偶来分为两种情况。

  1. 余数为0的数共有偶数个

1、cnt1为0,A,B都只能取余数为2的数

取余数221(2)212
玩家ABA(false)BAB
总和余210121

此时A一定输掉游戏,cnt2为0时同理。
2、 当cnt1和cnt2同时为0时,A一定输掉游戏
3、当cnt1和cnt2均不为零时,A先手取数,A只需先手取较少的数(看表易得,当A,则B一定会因为取出使得总和与三的余数为0而失败。

  1. 余数为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/

如果你在阅读过程中发现错误或不懂的地方,欢迎在评论去中指出或私聊,感谢阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值