題目描述
一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。
首先:位運算中異或的性質:兩個相同數字異或=0,一個數和0異或還是它本身。
當只有一個數出現一次時,我們把數組中所有的數,依次異或運算,最後剩下的就是落單的數,因爲成對兒出現的都抵消了。
依照這個思路,我們來看兩個數(我們假設是AB)出現一次的數組。我們首先還是先異或,剩下的數字肯定是A、B異或的結果,這個結果的二進制中的1,表現的是A和B的不同的位。我們就取第一個1所在的位數,假設是第3位,接着把原數組分成兩組,分組標準是第3位是否爲1。如此,相同的數肯定在一個組,因爲相同數字所有位都相同,而不同的數,肯定不在一組。然後把這兩個組按照最開始的思路,依次異或,剩餘的兩個結果就是這兩個只出現一次的數字。
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int size = data.size();
if(size ==0) return;
int resultExclusivOr = 0;
for(int i=0; i<size; ++i){
resultExclusivOr ^= data[i];
}
int indexOf1 = FindFirstBitIs1(resultExclusivOr);
for(int i=0; i<size; ++i){
if(IsBit1(data[i], indexOf1)){
*num1 ^= data[i];
}else{
*num2 ^= data[i];
}
}
}
int FindFirstBitIs1(int num){
int index = 0;
while(((num&1) == 0) && (index < 8*sizeof(int))){
num = num>>1;
++index;
}
return index;
}
bool IsBit1(int num, int index){
num = num >> index;
return(num & 1);
}
};