算法-數組中只出現一次的數字

1. 找出數組中只出現一次的數字

這個題目其實有兩種形式:

  1. 一個整型數組裏除了某一個數字之外,其他的數字都出現了兩次,找出這個只出現了一次的數字
    如數組 [1,2,2,1,3], 則目標數字爲 3

  2. 一個整型數組裏除了某兩個數字之外,其他的數字都出現了兩次,找出這兩個只出現了一次的數字
    如數組 [1,2,2,1,3,5], 則目標數字爲 3,5

2. 解法

2.1 只有一個不重複數字

思路:使用異或運算符^,0與其他數字異或的結果是那個數字,相等的數字異或得 0

  • 數組中除了某一個數字只出現了一次之外,其他數字都出現了兩次,所以可定義一個變量賦初始值爲0,用這個變量與數組中每個數字做異或運算,並將這個變量值更新爲那個運算結果,直到數組遍歷完畢,最後得到的變量的值就是數組中只出現了一次的那個數字
 public static int findOnceFrom2(int[] a) {
        int len = a.length, res = 0;
        for (int i = 0; i < len; i++) {
            res = res ^ a[i];
        }
        return res;
    }

2.2 有兩個不重複的數字

這個問題其實是基於以上問題的擴展,首先可知當只有一個數出現一次時,把數組中所有的數依次異或運算,最後剩下的就是落單的數,因爲成對出現的都抵消了。

  • 按照這個思路,首先還是先異或,最後剩下的數字肯定是A、B異或的結果 C,以數組 [1,2,2,1,3,5]爲例, 則 A=3(0011),B=5(0101),結果C=6(0110)。C 的二進制表示中 1 所在的位,其實就是A 和 B 的二進制表示中數值不同的位。我們取第一個1 所在的位數 index,可知是(0010 = 1<<index)即 index=1據此把原數組分成兩組,分組標準是數字第2位是否爲1。這樣成對的數字肯定在一個組中,因爲相同數字所有位的數值都相同,而不同的數肯定不在同一組。之後把這兩個組按照最開始的思路,依次異或,剩下的兩個結果就是這兩個只出現一次的數字
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {  
		 if(array == null || array.length <= 1){
	            num1[0] = num2[0] = 0; // 初始化爲 0
	            return;
	        }
	        int len = array.length, index = 0, sum = 0;
	        for(int i = 0; i < len; i++){
	            sum ^= array[i];
	        }
	        for(index = 0; index < 32; index++){
	            if((sum & (1 << index)) != 0) break; // 獲取第一個 1 所在位數 index
	        }
	        for(int i = 0; i < len; i++){
	            if((array[i] & (1 << index))!=0){ // 根據 index 將數組分爲兩部分
	                num2[0] ^= array[i];
	            }else{
	                num1[0] ^= array[i];
	            }
	        }
	        System.out.println(num1[0]+" "+num2[0]);
	        
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章