數組——數組中只出現一次的數字

1,問題描述

一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。

2,解題思路

有兩種解題思路:
(1)桶排序

  • 1)遍歷數組array,找到數組中最大值max;
  • 2)構建輔助數組a,長度爲max+1;
  • 3)遍歷數組array,array中的元素作爲a數組中的下標值,array中的元素每出現一次,a數組相對應下標的數組元素值加1(桶排序的思想);
  • 4)遍歷a數組,a數組中,元素值等於1的下標值就是所求值。

該解題思路有個弊端,例如,假如數組中的元素值很大的情況下,輔助數組a就會很大,這樣佔用很多的輔助空間。

(2)異或 (轉自牛客)

  • 1)首先明確異或運算的性質:兩個相同數字異或等於0,一個數和0異或還是它本身。
  • 2)該問題的簡單版本:當只有一個數出現一次時,我們把數組中所有的數,依次異或運算,最後剩下的就是落單的數,因爲成對兒出現的都抵消了。
  • 3)依照這個思路,我們來看兩個數(我們假設是AB)出現一次的數組。
    • 我們首先還是先異或,剩下的數字肯定是A、B異或的結果,這個結果的二進制中的1,表現的是A和B的不同的位;
    • 我們就取第一個1所在的位數( 從右向左方向中第一個1所在的位數,位數從0開始計數),假設是第3位,接着把原數組分成兩組。分組標準是第3位是否爲1。 如此,相同的數肯定在一個組,因爲相同數字所有位都相同,而不同的數,肯定不在一組。然後把這兩個組按照最開始的思路,依次異或,剩餘的兩個結果就是這兩個只出現一次的數字。

      例如,按序遍歷原數組時,假如3在第一個組,那麼有兩個3的話,另一個3肯定也在第一組。

3,源碼

package manduner;
/**
* @author Manduner_TJU
* @version 創建時間:2019年6月26日上午10:40:29
*/
public class 數組中只出現一次的數字 {
	public static void main(String[] args) {
		int[] array = {2,4,3,6,3,2,5,5};
		int[] num1 = new int[1];
		int[] num2 = new int[1];
		//FindNumsAppearOnce(array,num1,num2);
		FindNumsAppearOnce2(array,num1,num2);
	}

	//方法二:異或
    public static void FindNumsAppearOnce2(int[] array, int[] num1, int[] num2)    {
        int length = array.length;
        if(length == 2){
            num1[0] = array[0];
            num2[0] = array[1];
            return;
        }
        //計算異或結果
        int bitResult = 0;
        for(int i = 0; i < length; ++i){
            bitResult ^= array[i];
        }
        int index = findFirst1(bitResult);
        //按照第index位是否爲1的標準將原數組分成兩組,每一組分別做異或;
        for(int i = 0; i < length; ++i){
            if(isBit1(array[i], index)){
                num1[0] ^= array[i];
            }else{
                num2[0] ^= array[i];
            }
        }
        
        System.out.println(num1[0]);
        System.out.println(num2[0]);
    }
     
    private static int findFirst1(int bitResult){
        int index = 0;
        while(((bitResult & 1) == 0) && index < 32){
            bitResult >>= 1;
            index++;
        }
        return index;
    }
     
    private static boolean isBit1(int target, int index){
        return ((target >> index) & 1) == 1;
    }
    
    
    
    
    //方法一:桶排序
	public static void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
    	if(array==null||array.length<2) return;
        int max = array[0];
        for(int x : array){
            if(x >= max){
                max = x;
            }
        }
        
        int[] a = new int[max+1];
        for(int i=0;i<array.length;i++){
            a[array[i]]++;
        }
        
        for(int j=0;j<=max;j++){
            if(a[j]==1 && num1[0]==0){
                num1[0] = j;
            }else if(a[j]==1 && num2[0]==0){
                num2[0] = j;
            }else if(num1[0]!=0 && num2[0]!=0) {
            	break;
            }
        }
        //System.out.println(num1[0]);
        //System.out.println(num2[0]);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章