您的位置:首页 > 编程语言 > C语言/C++

LeetCode: Single Number II

2014-11-20 23:48 190 查看
人类解法我就不说了,最基础的hashtable计数,或者按位相加模3等等。现在主要看这个solution,代码来自stackoverflow, 但是那个解释我还是觉得不到位。。。

int singleNumber(int A[], int n) {
int one = 0;
int two = 0;
int not_three = 0;
for(int i=0; i<n; i++){
two |= one&A[i];
one ^= A[i];
not_three = ~(one&two);
one &= not_three;
two &= not_three;
}
return one;
}


代码很简洁就是看起来头大。简而言之,这个solution仍然是对每个bit进行计数,只不过是在原地计数,省空间省时间。

复习下最基本的异或操作:1^0=1, 0^1=1, 1^1=0, 0^0=0. 有没有发现,异或不仅可以a^a=0, 同时可以方便的对每个bit上的1进行计数。

变量one就是通过异或操作不断对每个元素每个bit上的1进行计数。如果上面代码没有not_three相关的操作,那么one中某bit上如果为1的话,表明数组中元素该bit上的1出现过奇数次。对于这道题这点信息是不够的,后面会继续解释。

变量two:如果数组中元素的某个bit上1出现过一次,那么one中的相应bit肯定会置1。当该bit第二次出现1时(即1出现了2次),那么two的对应bit会被置1记录该信息。也就是说,当某个bit上的1累加了两次时,one中对应的bit毫无疑问会置0,而two中对应的bit会被置1。

变量not_three:当数组中元素的某个bit上1出现第三次的时候,two对应bit上的1不变,而one对应bit会被置1。那么我们就有了出现三次1的bit位信息,即one&two。出现三次的1是题目要求过滤掉的,故有了one&=not_three; two&=not_three。

就整个数组而言,除了那个single number,每个bit上的1都会出现3n次从而被如上步骤过滤掉,余下的bit为1的信息,即one就是所查找的single number。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ leetcode