【力扣题解】2029-石子游戏 IX

156 阅读5分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述

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 获胜。

二、思路分析

1、石子分类

根据题意石子分三类,数量余3为0的称为类型0,余3为1的称为类型1,余3为2的称为类型2。

由于在题目规则上进行游戏时需要保证移除石子和不整除3,因此类型0的选取实际上是对总量无影响的,但是如果类型0出现次数为奇数,回合会交换;如果为偶数则回合交换会抵消,判断时可忽略。

2、枚举回合信息

这里我们暂时忽略类型0的选择,只枚举类型1和类型2;

当Alice第一回合选择类型1,Bob只能选择类型1,接着Alice只能选择类型2,Bob只能选择类型1:

1️⃣11 21 21 21……

如果Alice第一回合选择类型2,Bob只能选择类型2,接着Alice只能选择类型1,Bob只能选择类型2:

2️⃣22 12 12 12……

这里可以发现,实际上Alice第一回合选择之后就奠定了Bob整局选取石子的类型了,

那么如果Alice想每一次都赢,那么就必须在过程中让Bob不得已选择另一个类型的石子;

对于情况1️⃣来说:

①第一回合Bob如果没有1可选,那么直接在第一回合就输了,此时需保证类型1有且仅有1个

②第一回合平手,此时1的数量是2,第二回合Alice选择了2,此时如果Bob只有2可选也输了,后面的回合都是这种推演,这意味着类型2的数量应该大于或者等于类型1的数量

对于情况2️⃣来说:

①第一回合Bob如果没有2可选,那么直接在第一回合就输了,此时需保证类型2有且仅有1个

②第一回合平手,此时2的数量是2,第二回合Alice选择了1,此时如果Bob只有1可选也输了,后面的回合都是这种推演,这意味着类型1的数量应该大于或者等于类型2的数量

综合以上两种情况,只要类型1和类型2的石子数量都大于等于1,那么Alice总可以找到一个方案去赢。

3、考虑回合交换

我们还需要考虑一下类型0为奇数时导致的回合交换,这会使得玩家选取石子的类型发生变化,但由于石子类型为偶数的情况不会导致回合交换,因此我们可以直接假设类型0的数量为1,来看几个例子:

1)当类型0的石子出现在第一回合,有四种可能性,分别为:

① 01 12 12……

② 10 12 12……

③ 02 21 21……

④ 20 21 21……

在①和②情况下,如果Alice想赢得游戏,就需要出现01 12 11或者10 12 11 等等,也就是需要类型1的数量至少比类型2多3个,即是 类型1-类型2 >= 3

在③和④情况下,如果Alice想赢得游戏,就需要出现02 21 22或者20 21 22 等等,也就是需要类型2的数量至少比类型1多3个,即是 类型2-类型1 >= 3

2)当类型0的石子出现在第一回合之外,有四种可能性,分别为:

① 11 02 12 12……

② 11 20 12 12……

③ 22 01 21 21……

④ 22 02 21 21……

我们可以发现实际上这和1)的情况是一致的,不过是类型0的位置变换了,回合数增加了,但Alice赢得游戏所需的条件仍是相同的;

因此我们可以得出结论:类型0石子为奇数时,Alice获胜的条件为类型1的数量至少比类型2多三个 或者 类型2的数量至少比类型1多三个

4、总结

类型0数量为偶数时:类型1和类型2的石子数量都大于等于1;

类型0数量为奇数时:类型1的数量至少比类型2多三个 或者 类型2的数量至少比类型1多三个;

三、AC代码

class Solution {
    public boolean stoneGameIX(int[] stones) {
        int stone0 = 0;
        int stone1 = 0;
        int stone2 = 0;
        for (int stone : stones) {
            if (stone % 3 == 0) {
                stone0++;
            } else if (stone % 3 ==1) {
                stone1++;
            } else {
                stone2++;
            }
        }
        if (stone0 % 2 == 0) {
            return stone1 >= 1 && stone2 >= 1;
        }
        return stone1 - stone2 >= 3 || stone2 - stone1 >= 3;
    }
}