定义 all_xor(arr) := arr[0] ^ arr[1] ^ .. ^ arr[-1]
记这两个不同的数分别为 a 和 b
则 ab = a ^ b = all_xor(arr) # 存在两个相同数字的都被消去
因为 a != b,则 ab 的二进制表示中必然有一个为 1(因为 0^1=1)
根据这个位置的 1 将 nums 分为两组,则 a 和 b 分别在这两组数字中,分别求一次 all_xor 即可;
Python
class Solution:
def FindNumsAppearOnce(self , arr: List[int]) -> List[int]:
ab = 0 # 计算 a ^ b
for x in arr:
ab ^= x
r = ab & (~ab + 1) # 计算 ab 最右侧的 1
a = b = 0
for x in arr: # 根据 r 位置是否为 1 将 arr 分为两组
if r & x:
a ^= x
else:
b ^= x
return [a, b] if a < b else [b, a]