黑板上写着一个非负整数数组 nums[i]
。
Alice 和 Bob 轮流从黑板上擦掉一个数字,Alice 先手。如果擦除一个数字后,剩余的所有数字按位异或运算得出的结果等于 0
的话,当前玩家游戏失败。 另外,如果只剩一个数字,按位异或运算得到它本身;如果无数字剩余,按位异或运算结果为 0
。
并且,轮到某个玩家时,如果当前黑板上所有数字按位异或运算结果等于 0
,这个玩家获胜。
假设两个玩家每步都使用最优解,当且仅当 Alice 获胜时返回 true
。
示例 1:
输入: nums = [1,1,2] 输出: false 解释: Alice 有两个选择: 擦掉数字 1 或 2。 如果擦掉 1, 数组变成 [1, 2]。剩余数字按位异或得到 1 XOR 2 = 3。那么 Bob 可以擦掉任意数字,因为 Alice 会成为擦掉最后一个数字的人,她总是会输。 如果 Alice 擦掉 2,那么数组变成[1, 1]。剩余数字按位异或得到 1 XOR 1 = 0。Alice 仍然会输掉游戏。
示例 2:
输入: nums = [0,1] 输出: true
示例 3:
输入: nums = [1,2,3] 输出: true
提示:
1 <= nums.length <= 1000
0 <= nums[i] < 216
根据游戏规则,轮到某个玩家时,如果当前黑板上所有数字按位异或运算结果为 nums
中所有数字的异或结果为
当 nums
中所有数字的异或结果不为 nums
的长度奇偶性来分析 Alice 的获胜情况。
当 nums
的长度为偶数时,如果 Alice 必败,那么只有一种情况,就是 Alice 无论擦掉哪个数字,剩余所有数字的异或结果都等于
假设数组 nums
长度为
我们记 nums
擦掉第
等式两边同时异或
如果无论 Alice 擦掉哪个数字,剩余所有数字的异或结果都等于
我们将
上式共有 nums
的长度为偶数时,Alice 必胜。
如果长度为奇数,那么 Alice 擦掉一个数字后,剩余数字个数为偶数,也就是将偶数长度的情况留给 Bob,那么 Bob 必胜,也即 Alice 必败。
综上,当 nums
的长度为偶数,或者 nums
中所有数字的异或结果为
时间复杂度 nums
的长度。
class Solution:
def xorGame(self, nums: List[int]) -> bool:
return len(nums) % 2 == 0 or reduce(xor, nums) == 0
class Solution {
public boolean xorGame(int[] nums) {
return nums.length % 2 == 0 || Arrays.stream(nums).reduce(0, (a, b) -> a ^ b) == 0;
}
}
class Solution {
public:
bool xorGame(vector<int>& nums) {
if (nums.size() % 2 == 0) return true;
int x = 0;
for (int& v : nums) x ^= v;
return x == 0;
}
};
func xorGame(nums []int) bool {
if len(nums)%2 == 0 {
return true
}
x := 0
for _, v := range nums {
x ^= v
}
return x == 0
}