【劍指offer】面試題56:陣列中數字出現的次數【C++版本】
阿新 • • 發佈:2019-01-23
題目:
陣列中只出現一次的兩個數字
一個整形陣列中除了兩個數字之外,其他數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。
解題思路:
1.注意到時間複雜度是O(n)而空間複雜度是O(1)。
2.看到這種出現偶數次數的情況,都可以考慮使用異或進行解答,因為一個數異或它本身為0。
3.全部數異或之後能夠消除掉出現偶數次數的數字,結果為出現一次的兩個數字的異或結果。這個結果必然有一位不等於0,可以根據不等於0的這位把所有數字分成兩組,則每組各包含一個出現一次的數字。此時對兩組資料分別進行異或,兩個結果就是最後的兩個數字。
可以AC的解法【C++版本】
#include <vector>
#include <iostream>
using namespace std;
void FindNumsAppearOnce(vector<int> data, int* num1, int *num2);
int main() {
vector<int> data{ 1,1,2,2,3,4,4,5,5,6,6,7 };
int num1, num2;
FindNumsAppearOnce(data, &num1, &num2);
cout << num1 << endl;
cout << num2 << endl;
system("pause");
return 0;
}
void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) {
if (data.size() < 2)return;
*num1 = *num2 = 0;
int tmp = 0;
for (auto a : data) {
tmp = tmp ^ a;
}
if (tmp == 0)return;
int posi = 0;
//這裡進行一個判斷,即posi的大小不能大於int的位數大小
while (posi < 8*sizeof(int)) {
if (tmp & 0x1) {
break;
}
tmp = tmp >> 1;
posi++;
}
int scale = 1 << posi;
for (auto a : data) {
if (a & scale) {
*num1 = (*num1) ^ a;
}
else {
*num2 = (*num2) ^ a;
}
}
}