1. 程式人生 > >【劍指offer】面試題56:陣列中數字出現的次數【C++版本】

【劍指offer】面試題56:陣列中數字出現的次數【C++版本】

題目:

陣列中只出現一次的兩個數字

一個整形陣列中除了兩個數字之外,其他數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是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; } } }