【Java】 劍指offer(56-1) 數組中只出現一次的兩個數字

 

本文參考自《劍指offer》一書,代碼採用Java語言。html

更多:《劍指Offer》Java實現合集  java

題目

  一個整型數組裏除了兩個數字以外,其餘的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。數組

思路

  記住:兩個相同的數字異或等於0.post

  若是數組中只有一個數字只出現一次,咱們從頭至尾異或每一個數字,那麼最終的結果恰好是那個只出現一次的數字。測試

  而本題裏數組中有兩個數字只出現一次,若是可以將數組分爲兩部分,兩部分中都只有一個數字只出現一次,那麼就能夠解決該問題了。url

  求解方法:spa

  咱們依舊從頭至尾異或每一個數字,那麼最終的結果就是這兩個只出現一次的數字的異或結果,因爲兩個數不一樣,所以這個結果數字中必定有一位爲1,把結果中第一個1的位置記爲第n位。由於是兩個只出現一次的數字的異或結果,因此這兩個數字在第n位上的數字必定是1和0htm

   接下來咱們根據數組中每一個數字的第n位上的數字是否爲1來進行分組,剛好能將數組分爲兩個都只有一個數字只出現一次的數組,對兩個數組從頭至尾異或,就能夠獲得這兩個數了。blog

 

測試算例 get

  1.功能測試(數組中有多對重複的數字;無重複的數字)

Java代碼

//題目:一個整型數組裏除了兩個數字以外,其餘的數字都出現了兩次。請寫程序
//找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。

public class NumbersAppearOnce {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if(array==null || array.length<2)
            return;
        int resultExclusiveOR=0;
        for(int i=0;i<array.length;i++)
            resultExclusiveOR^=array[i];
        
        int indexOf1=0;
        while(((resultExclusiveOR&1)==0) && (indexOf1<=4*8)){
        	resultExclusiveOR=resultExclusiveOR>>1;  //只有n>>1不完整,要n=n>>1
            indexOf1++;
        }
        
        num1[0]=0;
        num2[0]=0;
        for(int i=0;i<array.length;i++){
            if(((array[i]>>indexOf1)&1)==1)
                num1[0]^=array[i];
            else
                num2[0]^=array[i];
        }
    }
}

  

收穫

  1.當一個數字出現兩次(或者偶數次)時,用異或^ 能夠進行消除。必定要牢記 異或的這個功能!

  2.將一組數字分爲兩組,能夠根據某位上是否爲1來進行分組,即根據和1相與(&1)的結果來進行分組。

  3.判斷某個數x的第n位(如第3位)上是否爲1,

    1)經過 x&00000100 的結果是否爲0 來判斷。(不能根據是否等於1來判斷)

    2)經過(x>>3)&1 是否爲0 來判斷

  4.將某個數x右移m位,必定要寫成 x=x>>m;而不能只寫成 x>>m;這個語句

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索