问题
思路
这个题朴素的思路就不说了,哈希即可。
说下位运算的思路,其实我不会做,参照了别人的做法。
大体思路如下:
1. 可以采用^操作,可以消除一样的数字。但是,这回导致一个问题,最后的结果是num1和num2亦或的结果。
2. 这是本题的精髓,考虑到如果有两个数字不能分开,但是如果一个数组中其余数字两两相同,只有一个数组不同,可以用上述的办法。我们着手考虑把这两个不同的数字分配到不同的数组当中即可。因为num1 != num2,所以num1 ^ num2的结果必然不为0,那么我们只需找出这两个数字在哪一位是不相同的,然后用这个MASK和所有数字^,这样自然可以把所有数字分配到两个不同的数组中。
代码
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int sz = data.size();
if(!sz) return;
int ans = 0;
for(int i = 0; i < sz; ++i){
ans ^= data[i];
}
std::bitset<32> bitarr(ans);
int mask = 1;
for(int i = 0; i < 32; ++i){
if( bitarr[i] ) break;
else mask <<= 1;
}
vector<int> arr1;
vector<int> arr2;
for(int i = 0; i < sz; ++i){
if( data[i] & mask ) arr1.push_back( data[i] );
else arr2.push_back( data[i] );
}
int sz1 = arr1.size();
ans = 0;
for(int i = 0; i < sz1; ++i){
ans ^= arr1[i];
}
num1[0] = ans;
int sz2 = arr2.size();
ans = 0;
for(int i = 0; i < sz2; ++i){
ans ^= arr2[i];
}
num2[0] = ans;
return;
}
};
代码1
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int sz = data.size();
if(!sz) return;
int ans = 0;
for(int i = 0; i < sz; ++i){
ans ^= data[i];
}
int mask = 1;
for(int i = 0; i < 32; ++i){
if( ans & mask ) break;
else{
mask <<= 1;
}
}
vector<int> arr1;
vector<int> arr2;
for(int i = 0; i < sz; ++i){
if( data[i] & mask ) arr1.push_back( data[i] );
else arr2.push_back( data[i] );
}
int sz1 = arr1.size();
ans = 0;
for(int i = 0; i < sz1; ++i){
ans ^= arr1[i];
}
num1[0] = ans;
int sz2 = arr2.size();
ans = 0;
for(int i = 0; i < sz2; ++i){
ans ^= arr2[i];
}
num2[0] = ans;
return;
}
};