Leetcode 137. Single Number II (位操作)
1 int singleNumber(vector<int>& nums) { 2 int a=0,b=0; 3 for(int n:nums){ 4 a = (a^n)&(~b); 5 b = (b^n)&(~a); 6 } 7 return a; 8 }
思想是利用位操作(或、与、异或、非)的交换和结合性。设计一个过程,使得第一次输入某个数n时,a=n,输入两次或三次n后,a=0;
做一次简单计算可以理清这个过程,假设只输入三次同一个数字n:
a1 = (0^n) & (~0) = n
b1 = (0^n) & (~n) = 0
a2 = (n^n) & (~0) = 0
b2 = (0^n) & (~0) = n
a3 = (0^n) & (~n) = 0
b3 = (n^n) & (~0) = 0
可见第三次输入后a和b的状态回到了原位。
设 F(n) 为输入一次n,上述式子可表达为:
F(n) = (n,0)
F(n) * F(n) = (0,n)
F(n) * F(n) * F(n) = (0,0)
同时,因为位运算的交换和结合性,我们可以发现 F(x) 具有这样的性质:
F(a) * F(b) = F(b) * F(a)
由此我们可以做这样一个推广:
F(a) * F(n) * F(b) *... (其中F(n)出现一次,其余出现三次)
= F(a)*F(a)*F(a)*F(b)*F(b)*F(b)*...*F(n) = F(n) = (n,0)
浙公网安备 33010602011771号