给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字。
对于2*n+1个数字用异或就行了,而在此题将所有数异或之后得到的是两个落单的数的异或结果,没办法将结果拆分成两个落单的数。但因为两个落单数不同,所以肯定存在某个位k,使得两落单数在第k位上一个为0另一个为1,怎么找到这个k? 找异或结果中1出现的位置即可。只需找到最小的这个k,然后将在k位上为0的所有数做异或,其他的在k位为1的所有数也做另外的异或,这样最终可以得到两个落单的数。
class Solution {
public:
/**
* @param A : An integer array
* @return : Two integers
*/
vector<int> singleNumberIII(vector<int> &A) {
// write your code here
int Xor = 0, n = A.size();
for ( int i = 0; i < n; ++i ) Xor ^= A[i];
int k = 0;
while ( Xor % 2 == 0 )
{
++k;
Xor >>= 1;
}
int r1 = 0, r2 = 0;
for ( int i = 0; i < n; ++i )
{
int kb = (A[i]>>k) % 2;
if ( kb == 0 ) r1 ^= A[i];
else r2 ^= A[i];
}
vector<int> res;
res.push_back(r1);
res.push_back(r2);
return res;
}
};