1. 程式人生 > >leetCode 41.First Missing Positive (第一個丟失的正數) 解題思路和方法

leetCode 41.First Missing Positive (第一個丟失的正數) 解題思路和方法

First Missing Positive 

Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.

思路:這個題剛開始是沒有思路的,難就難在O(n)時間內常數量空間,所以此題較為考察思維敏捷性。其解題核心思想是將陣列的第i位存正數i+1。最後再遍歷一次即可。

其他人的思想,我也是看了這個思想自己寫的程式碼。

雖然不能再另外開闢非常數級的額外空間,但是可以在輸入陣列上就地進行swap操作。

思路:交換陣列元素,使得陣列中第i位存放數值(i+1)。最後遍歷陣列,尋找第一個不符合此要求的元素,返回其下標。整個過程需要遍歷兩次陣列,複雜度為O(n)

下圖以題目中給出的第二個例子為例,講解操作過程。

媽蛋,這題掙扎好久。首先思路上,其次臨界條件,這題和下面題異曲同工:

n個元素的陣列,裡面的數都是0~n-1範圍內的,求陣列中重複的某一個元素,沒有返回-1, 要求時間效能O(n) 空間效能O(1)。

程式碼還是比較簡單,如下:
public class Solution {
    public int firstMissingPositive(int[] nums) {
        if(nums.length == 0)
            return 1;
        //第i位存放i+1的數值
        for(int i = 0; i < nums.length;i++){
            if(nums[i] > 0){//nums[i]為正數,放在i+1位置
                //如果交換的資料還是大於0且<i+1,則放在合適的位置,且資料不相等,避免死迴圈
                //這個while是關鍵,其他都是沒有難度的
                while(nums[i] > 0 && nums[i] < i+1 && nums[i] != nums[nums[i] -1]){
                    int temp = nums[nums[i]-1];//交換資料
                    nums[nums[i]-1] = nums[i];
                    nums[i] = temp;
                }
            }
        }
        //迴圈尋找不符合要求的資料,返回
        for(int i = 0; i < nums.length;i++){
            if(nums[i] != i+1){
                return i+1;
            }
        }
        //如果都符合要求,則返回長度+1的值
		return nums.length + 1;
    }
}