题目:
Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
思路:
这个题目,要分析每个数字的每一个bit。把所有数字都写成32位二进制形式。假设分析二进制的第i位,如果所有数字的二进制第i位之和为3的倍数,则说明那个Single Number的二进制第i位为0;否则为1。这样就可以把Single Number的二进制的每一位都判断出来,进而求出Single Number。注意int的符号问题,为了不受符号影响,我们把所有参与运算的数字都转换成unsigned int形式,最后再把Single Number转换成int即可。
这种方法可以推广到every element appears four times except for one
、every element appears five times except for one
、甚至更多times except for one。
代码实现:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int len = 32;
unsigned int mask = 1;
unsigned int ans = 0;
while (len--){
int bit_sum = 0;
for (int i = 0; i < nums.size(); ++i){
unsigned int t = nums[i];
if (t & mask){
++bit_sum;
}
}
if (bit_sum % 3 != 0){
ans |= mask;
}
mask <<= 1;
}
return (int)ans;
}
};
discuss:
/*
思路(暂时不明白):方法很简单,就是把ones和twos分别当做两个集合,然后第一次出现就放在ones,第二次出现就在ones中删除并放在twos,第三次出现就从twos中删除,这样最终ones中就留下了最后的结果。
参考https://blog.csdn.net/weixin_38246633/article/details/90766047
*/
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ones = 0, twos = 0;
for (int i : nums){
ones = (ones ^ i) & ~twos;
twos = (twos ^ i) & ~ones;
}
return ones;
}
};