1. 程式人生 > >[array] leetcode - 41. First Missing Positive - Hard

[array] leetcode - 41. First Missing Positive - Hard

put 基本原理 理解 log 開始 blog ons i+1 right

leetcode - 41. First Missing Positive - Hard

descrition

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)。如果沒有時間復雜度的現在,我們可以對數組進行排序,並檢查順序數組中 positive 數的缺失情況即可,時間復雜度為O(nlog(n))。

在有時間復雜度限制的情況下,我們需要進一步分析題目的特點。

  • 此處還需要註意的是,positive 是指那些大於 0 的數
  • 要找到第一個缺失的正整數(所謂的第一個正整數,是指從 1 開始計數,第一個缺失的正整數)

基本原理:對於 k 個正整數(允許重復),第一個缺失的值必然在區間 [1,k+1] 內。可以想象成,將 k 個球放到 k+1 個箱子裏,那麽必然有至少有一個箱子是空的。

對於長度為 n 的整型數組 arry[],假設正整數的個數為 k 個,k<=n,那麽缺失的值必然在區間 [1,k+1]內,我們可以將區間映射到 [0,k](當 k=n 時,區間為[0,n-1])。
(輔助理解:[1,k+1] 可以看成是從 1 開始順序編號的箱子,直到 k+1,我們現在有 k 個正整數,正整數的數值表示起要放到幾號桶,因為我們最多只有 k 個正整數,那麽必然至少有一個桶時空的)

根據以上分析,對於任意正整數 1<=arry[i]<=n,我們可以從左邊到右(從編號1開始到k)將其放到 arry[i]-1 的位置。滿足 1<=arry[i]<=n 條件的數最多有 n 個。最後檢查,如果存在 arry[i] != i+1 ,那麽 i+1 就是缺失的第一個正整數,最極端的情況是 n 個數都滿足 arry[i] == i+1,此時第一個缺失的正整數為 n + 1。(註意!!從左往右遍歷)

具體實現如代碼所示。註意,滿足 1<=arry[i]<=n 條件的正整數有可能存在重復,因此需要檢查即將要放置的目標位置是否已經滿足條件,如果不滿足條件才能放置。

code

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution{
public:
    // time-O(n), space-O(1)
    int firstMissingPositive(vector<int>& nums){
        int n = nums.size();
        // put the element to the right place
        // i must be increased from 0 to n, becasue we need to satisfy the lower number first
        for(int i=0; i<n; i++){
            while(nums[i] > 0 && nums[i] <= n && nums[nums[i]-1] != nums[i]){
                // note: nums[nums[i]-1] != nums[i] indicate the place nums[nums[i]-1] hasn‘t satisfied
                // so we can place the nums[i] to nums[nums[i]-1]
                swap(nums[i], nums[nums[i]-1]);
            }
        }

        // find the first missing positive
        for(int i=0; i<n; i++){
            if(nums[i] != (i+1))
                return i+1;
        }

        return n + 1;
    }
};

int main()
{
    return 0;
}

[array] leetcode - 41. First Missing Positive - Hard