Single Number II Given an array of integers, every element appears three times except for one. Find that single one.
一、常规,统计各数字各二进制位出现的次数。
int singleNumber(vector<int>& nums) {
intlength = nums.size();
int result = 0;
for(int i = 0; i<32; i++){
int count = 0;
int mask = 1<< i;
for(int j=0; j<length; j++){
if(nums[j] & mask)
count++;
}
if(count %3)
result |= mask;
}
return result;
}
二、对方法1的优化,设置变量one、two分别用于统计nums中出现1次和两次的数,
1. 考虑one, 如果某一位出现奇数次,则该位出现在one中,如果出现偶数次,则该位被清零。实现这样的逻辑的就是^(异或)运算。因为one直接跟A[i]相关(可将A[i]看作假想的zero变量), 所以自然应该有代码: one ^= A[i];
2. 考虑two, 如果某一位出现1次,则该位不出现在two中,如果出现两次则出现在two中。既然我们已经有了one,且有假想的zero(A[i]),显然two应该在one中,zero中同时出现该位时,才记录该位,实现这样的逻辑中“同时"的是&(与)运算,实现"才"的是|(或)运算,所以自然应该有代码: two |= A[i] & one;
3. 考虑某一位第三次出现:如果该位第三次出现,那么由之前描述,该位一定同时出现在two中和zero(A[i])中,这时从one和two中只除掉这一位;否则,one和two在这一位上的值不受影响。为实现这样的逻辑中的"同时",自然有代码: int t = one & two(t中记录同时出现在one和two中的位); 与"这时..只除掉..否则..不受影响"对应的逻辑运算为&(与运算)和~(非运算),因此自然有代码: a &= ~t; b &= ~t;
class Solution {
public:
int singleNumber(vector<int>& nums) {
int one = 0, two = 0;
for (int i=0; i<nums.size(); ++i) {
two |= nums[i] & one;
one ^= nums[i];
int t = one & two;
one &= ~t;
two &= ~t;
}
return one;
}
};