这是一道位运算好题,下面说一下位运算的主要思路:
1.因为只有一个数只出现了一次,而其他的数都出现了3次,那么在32位二进制数中,如果我们对每个数每一位出现1的个数进行统计,然后把这个结果%3后在放回这一位上,就得到了剩下的那个数在这个位上的数,什么意思呢?
这里来举几个例子
11011 11011 11011 01001
这里三个重复的11011,我们先从最高位看,遍历完发现有三个1,说明是重复的3个数产生的,也就说明了剩下的那个数首位不为1,这样通过%3就可以知道剩下那个数的对应位是1还是0(因为数的总数是3n+1,每次遍历完后对应位1的个数余3也只能是0或者1,不用担心2的产生)。
2. 然后我们得到了每一位上的1的个数余3后,也就知道了剩下一个数在这个位上是0还是1,那么我就把它(0或者1)移回到对应位上,像上面那个例子,从低到高数最高位是第5位,那么我就把得到的0<<5,左移五位,“放”到最高位上。然后每次得到对应位的时候与前面得到的“拼起来就行了”,运用按位或运算符。
(比如上面那个最高位得到了0->00000,下一位发现有四个1,余3得1,然后左移四位到第四位,01000,再与前面的拼起来,00000|01000=01000,然后以此类推,到最后一位的时候,则会有01000|00001=01001,即是答案)。
代码如下:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int i, j;
int res=0;
for(i=0;i<32;i++)
{
int sum = 0;
for(j=0;j<nums.size();j++)
{
sum += ((nums[j]>>i)&1);
}
res |=(sum%3)<<i;
}
return res;
}
};