劍指offer之數組中出現的次數

1. 題目

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

2. 思路

首先,能夠想一下,若是數組中只有一個數字只出現了一次,其餘數字都出現了兩次,怎麼找出這個數字呢?根據這個問題能夠想到異或的一個性質:加任何一個數字異或它本身都等於0。也就是說,若是從頭至尾異或每一個數字,那麼最終的結果就是那個只出現了一次的數字,由於那些成對出現的數字都在異或中抵消了。數組

根據上面的思路,咱們異或數組中的全部數字,這裏能夠獲得一個不爲 0 的數字,這個數字是數組中兩個只出現一次數字的異或結果。由於這個結果不爲 0,所以咱們能夠從右向左找出這個數字二進制第一個不爲 0 的數字,根據這一位將數組分爲兩個子數組(長度爲 2),這一位爲 1 的數字放在第一個子數組中,這一位爲 0 的數字放在第二個子數組中。對這兩個子數組進行異或操做,便可獲得最終的結果。code

3. 代碼

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;
    }
}
相關文章
相關標籤/搜索