1. 程式人生 > >leetcode41 - First Missing Positive - hard

leetcode41 - First Missing Positive - hard

posit while pos ssi mis 個數 一個數 emp ger

Given an unsorted integer array, find the smallest missing positive integer.
Example 1:
Input: [1,2,0]
Output: 3
Example 2:
Input: [3,4,-1,1]
Output: 2
Example 3:
Input: [7,8,9,11,12]
Output: 1
Note:
Your algorithm should run in O(n) time and uses constant extra space.

桶排序思想:把東西放在它應處的位置。
本題如果是三個數字,那這三個位置是開給123的,如果5個數字,五個位置是開給12345的。如果進來無效數字:<=0或者>length,那就會占掉本來期待的數字的位置。
1.遍歷數字,讓所有有效數字都跑到自己該在的桶裏。
2.遍歷每個桶,第一個發現的裝錯數字的桶,它本應裝的數字就是我們期待的first missing positive。

細節:
1.讓所有有效數字跑到自己桶裏的方法就是,如果看到一個數,它在當前長度的數組裏應該有一席之位([1, length]),而且那個位置上當前不是已經有這個數了(nums[nums[i] - 1] != nums[i]),那就swap。同時註意的是換過來的數字還沒檢查過,要接著檢查,所以這裏用while循環不是用if。
2.註意最後沒有發現裝錯東西的桶,就說明現在都按12345排了什麽數字都不缺,那還要返回下一個length+1作為答案。
3.本題0或者負數或者多出來的無家可歸的[1,length]數字都是無效數字,不用處理,就做一些占位符,不要擋道那些應該可以放到正確位置的數字的道就行,等著最後一輪清掃被揪出來。

實現

class Solution {
    public int firstMissingPositive(int[] nums) {
        if (nums == null) {
            return 1;
        }
        
        for (int i = 0; i < nums.length; i++) {
            // numbers that can be set in right place, and the place is not occupied by another this number.
            while
(nums[i] >= 1 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]) { swap(nums, i, nums[i] - 1); } } for (int i = 0; i < nums.length; i++) { if (nums[i] != i + 1) { return i + 1; } } return nums.length + 1; } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }

leetcode41 - First Missing Positive - hard