劍指offer第二版-56.數組中只出現一次的兩個數字

本系列導航:劍指offer(第二版)java實現導航帖

面試題56:數組中只出現一次的兩個數字

題目要求:
一個整數數組里除了兩個數字出現一次,其他數字都出現兩次。請找出這兩個數字。要求時間復雜度為o(n),空間復雜度為o(1)。

解題思路:
這道題可以看成“數組中只出現一次的一個數字”的延伸。如果所有數字都出現兩次,只有一個數字是出現1次,那么可以通過把所有所有進行異或運算解決。因為x^x = 0。
但如果有兩個數字出現一次,能否轉化成上述問題?依舊把所有數字異或,最終的結果就是那兩個出現一次的數字a,b異或的結果。因為a,b不想等,因此結果肯定不為0,那么結果的二進制表示至少有一位為1,找到那個1的位置p,然后我們就可以根據第p位是否為1將所有的數字分成兩堆,這樣我們就把所有數字分成兩部分,且每部分都是只包含一個只出現一次的數字、其他數字出現兩次,從而將問題轉化為最開始我們討論的“數組中只出現一次的一個數字”問題。

實例分析(以2,4,3,6,3,2,5,5為例):

相關數字的二進制表示為:
2 = 0010       3 = 0011       4 = 0100
5 = 0101       6 = 0110

步驟1 全體異或:2^4^3^6^3^2^5^5 = 4^6 = 0010
步驟2 確定位置:對于0010,從右數的第二位為1,因此可以根據倒數第2位是否為1進行分組
步驟3 進行分組:分成[2,3,6,3,2]和[4,5,5]兩組
步驟4 分組異或:2^3^6^3^2 = 6,4^5^5 = 4,因此結果為4,6。

代碼實現:

package chapter6;

/**
 * Created with IntelliJ IDEA
 * Author: ryder
 * Date  : 2017/8/17
 * Time  : 10:58
 * Description:數組中數字出現的次數
 * 有兩個數字分別出現一次,其他的都出現兩次,找到這兩個數字
 **/
public class P275_NumberAppearOnce {
    public static int[] findNumsAppearOnce(int[] data){
        int result = 0;
        for(int i=0;i<data.length;i++)
            result^=data[i];
        int indexOf1 = findFirstBit1(result);
        int ret[] = new int[]{0,0};
        if(indexOf1<0)
            return ret;
        for(int i=0;i<data.length;i++){
            if((data[i]&indexOf1)==0)
                ret[0]^=data[i];
            else
                ret[1]^=data[i];
        }
        return ret;
    }
    public static int findFirstBit1(int num){
        if(num<0)
            return -1;
        int indexOf1 = 1;
        while (num!=0){
            if((num&1)==1)
                return indexOf1;
            else{
                num = num>>1;
                indexOf1*=2;
            }
        }
        return -1;
    }
    public static void main(String[] args){
        int[] data = new int[]{2,4,3,6,3,2,5,5};
        int[] result = findNumsAppearOnce(data); // 4,6
        System.out.println(result[0]);
        System.out.println(result[1]);

    }
}

運行結果

4
6
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容