黑板上寫著一個非負整數數組 nums[i] 。Alice 和 Bob 輪流從黑板上擦掉一個數字,Alice 先手。如果擦除一個數字后,剩余的所有數字按位異或運算得出的結果等于 0 的話,當前玩家游戲失敗。 (另外,如果只剩一個數字,按位異或運算得到它本身;如果無數字剩余,按位異或運算結果為 0。)
換種說法就是,輪到某個玩家時,如果當前黑板上所有數字按位異或運算結果等于 0,這個玩家獲勝。
假設兩個玩家每步都使用最優解,當且僅當 Alice 獲勝時返回 true。
示例:
輸入: 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 仍然會輸掉游戲。
解題思路
奇偶不變
因為ALice和Bob是輪流取數字的,所以如果剛開始的元素個數是偶數個,那么Alice每次取元素時,元素都是偶數。
S^nums[i]=Si
設Si為數組去掉第i個元素以后的異或的結果,S為所有元素異或的結果,即有Sinums[i]=S,變形得Snums[i]=Si
反證法
在數組長度為偶數并且S!=0(因為如果S=0,那么就勝負已經確定了)的情況,假設無論取走的元素是哪個,都有Si=0
即S0=0,S1=0…,等價于S0S1S2…=0,代入S^nums[i]=Si
得
(S^nums[0])^(S^nums[1])^....=0
(S^S...)^(nums[0]^nums[1]....)=0
又因為S為所有元素異或的結果,并且數組長度為偶數,所以有偶數個S,因此
S^S…(奇數個S)=0,即S=0,與S!=0矛盾,所以可以得出無論取走的元素是哪個,都不存在Si=0,也就是說數組長度為偶數的那一方,可以使得另一方永遠產生不了剩下元素異或結果為0的情況。
所以Alice要想贏,只需要兩種情況
- 原數組異或的結果是0,因為Alice是先手,所以直接就贏了
- 原數組的長度為偶數
代碼
class Solution {public boolean xorGame(int[] nums) {int res=0;if((nums.length&1)==0) return true;for (int num : nums) {res^=num;}return res==0;}
}