算法總結之 數組中未出現的最小正整數


 給定一個無序整型數組arr,找到數組中未出現的最小正整數

 

解題思路非常好,需要好好學習一下,很邏輯

 如果arr長度為N, 最優解可以做到時間復雜度O(N) 額外空間復雜度O(1)

  1、遍歷arr之前生成兩個變量, l  r   初始值 l=0   r=N

  2、從左到右遍歷arr,arr[l]

  3、如果arr[l]=l+1 沒有遍歷arr[l]之前,arr已經包含的正整數范圍是[1,l],此時出現了arr[l]=l+1的情況,所以arr包含的正整數范圍可以擴展到[1,l+1]  即令 l++  

  4、如果arr[l]<=l  沒有遍歷arr[l]之前,arr在后續最優的情況下可能包含的正整數范圍是[l,r],已經包含了的正整數的范圍是[1,l],所以需要[l+1,r]上的數。而此時出現了arr[l]<=l,說明[l+1,r]范圍上的數少了一個,所以

       arr在后續最優的情況下,可能包含的正整數范圍縮小了,變為[l,r-1],此時把arr最后位置的數(arr[r-1])放在位置l上,下一步檢查這個數,然后令r--,

   5、如果arr[l]>r,與上面同理的,把arr最后位置的數(arr[r-1])放在位置l上,下一步檢查這個數,然后令r--

   6、如果arr[l]=arr[arr[i]-1],如果上面兩個都沒中,說明 arr[l]是在[l+1,r]范圍上的數,而且這個數應該放在arr[l]-1位置上,可是此時發現arr[l]-1位置上的數已經是arr[l], 說明出現了兩個arr[l]呀,既然在[l+1,r]上出現了         兩個arr[l],重復了。那么[l+1,r]范圍上的數又少了一個,所以與步驟4和5一樣,把arr[r-1]放在位置l上,下一步檢查,然后另r--

  7、 如果都沒有中,說明發現了[l+1,r]范圍上的數,並且沒有重復。那么arr[l]應該放在arr[l]-1位置上,所以把l位置上的數和arr[l]-1位置上的數交換,下一步繼續遍歷l位置上的數

  

   最終l和r會碰撞在一起(l==r) arr已經包含的正整數范圍是[1,l],

 

package TT;

public class Test83 {

    public static int missNum(int[] arr){
        int l =0;
        int r = arr.length;
        
        while(l<r){
            
            if(arr[l]==l+1){
                l++;
            }else if(arr[l]<=l || arr[l]>r || arr[arr[l]-1]==arr[l]) {

                arr[l]=arr[--r];
            }else {
                swap[arr,l,arr[l]-1];
            }
        }
        return l+1;
    }
    
    
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM