一個整型數組裏面除兩個數字以外,其餘數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間複雜度是O(N),空間複雜度是O(1)。java
首先,能夠想一下,若是數組中只有一個數字只出現了一次,其餘數字都出現了兩次,怎麼找出這個數字呢?根據這個問題能夠想到異或的一個性質:加任何一個數字異或它本身都等於0。也就是說,若是從頭至尾異或每一個數字,那麼最終的結果就是那個只出現了一次的數字,由於那些成對出現的數字都在異或中抵消了。數組
根據上面的思路,咱們異或數組中的全部數字,這裏能夠獲得一個不爲 0 的數字,這個數字是數組中兩個只出現一次數字的異或結果。由於這個結果不爲 0,所以咱們能夠從右向左找出這個數字二進制第一個不爲 0 的數字,根據這一位將數組分爲兩個子數組(長度爲 2),這一位爲 1 的數字放在第一個子數組中,這一位爲 0 的數字放在第二個子數組中。對這兩個子數組進行異或操做,便可獲得最終的結果。code
public class F56FindNumsAppearOnce { public void solution(int[] data,int[] result){ if(data==null || data.length<2) return ; int resultExclusiveOR = 0; // 將數組中全部數字都進行異或操做 for(int i=0;i<data.length;i++) resultExclusiveOR ^= data[i]; // 找出異或操做結果二進制第一個不爲 0 的位置 int indexOf1 = findFirstBitsIs1(resultExclusiveOR); // 根據 indexOf1 位置上是否 1 分爲兩個數組 for(int i=0;i<data.length;i++){ if(isBit1(data[i],indexOf1)){ result[0] ^= data[i]; }else{ result[1] ^= data[i]; } } } private int findFirstBitsIs1(int num){ int index = 0 ; while((num&1)== 0){ num>>=1; index++; } return index; } private boolean isBit1(int num,int index){ num >>= index; return (num&1)==1; } }