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

2022-05-30 11:15:09 字數 1225 閱讀 6311

題目:乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是o(n),空間複雜度是o(1)。

思路:首先交待一下異或的基本性質:2個相同的數異或等於0,且異或操作(^)滿足結合律和交換律。

再來考慮一種簡單一點的情況:乙個陣列中只有乙個元素出現唯一的一次,而有其他元素都出現2次。

那麼我們用0依次異或陣列中每乙個元素,得到的就是那個唯一的元素。因為我們可以利用交換律和結合律將相同的元素移動到一起,那麼在利用結合律,相同的元素兩兩先異或,得到0,最後得到很多0和唯一的元素異或,所以最終的答案就是那個唯一的元素。

所以,如果我們能把原來問題中的陣列,分成2個子陣列,使得每個子陣列中都只有乙個唯一的元素以及很多成對的元素,那麼我們就可以求出每個子陣列中唯一的元素,最終就可以得到原陣列中2個出現次數唯一的元素。

方法是這樣的:

1. 首先陣列中所有元素依次異或,因為相同的元素異或得到0,所以最終的答案就等於那2個唯一的元素a^b的值。

2. 因為a,b不同,所以異或得到的答案肯定是不等於0的,那麼我們就找到a^b的二進位制表示中第乙個為1的位,假如是第k位。而a,b兩個數在第k位上是不同的,乙個為0,乙個為1

3. 接下來我們將第k位是1的分成一組,第k位是0的分成一組,如果2個元素相同,那麼他們第k位肯定是一樣的,所以肯定被分到同一組中。而a,b則被分到2組中去了。

然後我們就可以在每個分組中異或每乙個元素,最終就可以得到那2個唯一的元素。

**:

#include using

namespace

std;

//判斷乙個數二進位制(從右往左)第幾位是1,並返回

int getfirstone(int

num)

return

pos;}//

判斷乙個數第pos位置是1還是0

bool isone(int num,int

pos)

//得到兩個只出現一次的數字,首先將所有元素異或,·····見思路即可

int getnum(int a,int len,int &num1,int &num2)

else

}}int

main()

;

int len=sizeof(a)/sizeof(int

); getnum(a,len,num1,num2);

cout

<"

"return0;

}

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

題目是這樣敘述的 在乙個陣列中除兩個數字只出現1次外,其它數字都出現了2次,要求盡快找出這兩個數字。要求 時間複雜度為o n 空間複雜度為o 1 請看我的分析 將這道題簡單化 乙個陣列中只有乙個數字出現一次,其他數字都是成對出現的,這時我們可以根據異或運算子的特性 a b a b 0 a a 我們可...

找出只出現一次的兩個數字

乙個整形陣列裡,除了兩個數字之外,其他的數字都出現了兩次,找出這兩個只出現一次的數字,例如陣列,找出7和9。之前做過乙個陣列中只有乙個只出現一次的數字,用亦或的方法,同理,找兩個數字,先把所有數字亦或,最後的結果是兩個只出現一次的數亦或的結果,這個結果中,出現1的位置說明兩個元素當前位不相等,可以根...

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

劍指 offer 56 i.陣列中數字出現的次數 大意 找出陣列中只出現一次的兩個數 其它出現兩次 思路 思路 首先需要知道乙個前置問題 找出陣列中只出現一次的乙個數 其它出現兩次 顯然,對整個陣列進行異或操作即可。那麼,我們是否有可能將本題中的陣列分隔成兩部分呢 不要求連續 答案是肯定的 我們仍然...