数组中有若干个数,有两个数只出现一次,其余的数都出现了两次,求出这两个单独出现的数。
leetcode260
假设两个数分别为a和b,思路就是先每个异或,然后得出a和b相异的位,结果为ans
然后取出ans最后为1的位,把原来的数组分开,再异或一次,得到答案。
这里取ans最后一位1的操作很巧妙:
ans = ans & (-ans)
假设一个数ans为xxxxxxx10000,需要返回的是000000010000。
先将ans取相反数,按照补码的操作,xxxxxx10000 -> XXXXXX01111-> XXXXXX10000
大写X表示和原来x都是相反的位。所以得到00000010000
另外,c++中输出二进制需要技巧:
cout<<hex<<static_cast<unsigned int>(ans)<<endl;
cout<<oct<<static_cast<unsigned int>(ans)<<endl;
cout<<dec<<static_cast<unsigned int>(ans)<<endl;
cout<<bitset<sizeof(unsigned int) * 8>(ans)<<endl;
原题的代码如下:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int ans = 0;
for(int n: nums)
ans = ans xor n;
ans = ans & (-ans);
int a = 0, b = 0;
for(int n: nums)
if(n & ans)
a = a xor n;
else
b = b xor n;
return {a, b};
}
};
在这里补一下各种码的区别:
原码:第一位为符号位,后面的是数值
反码:正数的反码是它自己,负数的反码:对于负数的原码,第一位符号位不变,其余各位取反
补码:正数的补码是它自己,负数的原码取反码后+1,就是负数的补码。