求數組裏不存在的最小正整數

題目:
給定一個長度爲N整形數組a[],所有數據爲正整數,且允許重複。要求尋找數組中不存在的最小正整數。

最初的思路是對數組進行排序,然後再從1開始比對,那個數沒出現,它就是答案。這樣做效率太低,然後想了另一種辦法。
利用哈希表,定義一種關係:定義一個大小爲(N/32+1)的整形數組b,因爲一個整形數據有32位,假設b[0]的第一位是1,第二位是2,·····,所以b[0],就可以存儲1-32。此時,如果我從數組a中讀取的第一個數a[0]=20,那麼用位運算b[0] |= (1<<20-1),也可以表示爲b[a[0]/32] |= (1<

public class ArrayMin {

    public static void main(String[] args){
        int[] a={4 ,7,58,6,5,3,74,32,68,41,85,2,34,7,79512,3,4,57,2,1,6,5,46813,62145};
        System.out.println(arrayMin(d));
    }

    private static int arrayMin(int [] arr){

        int N=arr.length;
        int [] arr_temp=new int[N/32+1];

        for(int i=0;i<N;i++){//遍歷數組a的數據,並映射到數組b
            if(arr[i]<=N)
                arr_temp[arr[i]/32]|=(1<<(arr[i]%32-1));        
        }


        for(int i=0;i<arr_temp.length;i++){//尋找第一個是0的位
            for(int j=0;j<32;j++){
                if((arr_temp[i]>>j&1)==0)
                    return (i+j+1);
            }
        }
        return 0;
    }

}

再細細想想:假設數組中每個數據是任何整數的概率是相同的,也就是a[i]=n(0< n <=Integer.MAX_VALUE)的概率是(1/Integer.MAX_VALUE)。那麼答案是1的概率是不是很大?只要數組中不存在1,答案就是1;答案是2的條件是:存在1並且不存在2,後面的數字要求越來越高,所以,我認爲,前20個數字中某一個數爲答案的概率幾乎接近1了,所以進一步提高效率就可以只把a[i]<=20的數映射到數組b裏,這樣時間複雜度和空間複雜度都可以進一步優化,當然,這樣也是存在風險的,所以可以根據實際情況去分析。
另一種情況:假如數據符合正態分佈(現實中很多數據符合),那麼根據正太分佈的那個概率公式,只映射a[i]<=μ-σ(或更小)的數據就幾乎可以獲得答案了。

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