1. 程式人生 > >First Missing Positive解題報告

First Missing Positive解題報告

其實看到這種hard型別的題目,還是有點緊張的,但有驚無險,一次就過了。

題目描述

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

大意就是說,給你一堆毫無規則的正數,你要給出其中不包含的正數裡面最小的那一個。

額外建立陣列法

一開始我其實想到了那個查詢第K大元素的典型問題,但是排序似乎太浪費時間了,畢竟我們只是要檢驗一種存在性,而不是獲得一種有序性,那麼如何驗證一個元素的存在呢,一個簡單的方法是將數組裡這個元素出現的位置置一,而把其他位置置為零。除此之外,由於資料的連續性特徵,陣列的大小隻需設定為給出的元素的數目即可。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) { 
    	int * x = new int[nums.size()]();
    	for (int i = 0; i < nums.size(); i++) {
    		if (nums[i] > 0 && nums[i] <= nums.size()) {
    			x[nums[i]-1] = 1;
    		}
    	}
    	int result = nums.size()+1;
    	for (int i = 0; i < nums.size(); i++) {
    		if (!x[i]) {
    			result = i+1;
    			break;
    		}
    	}
    	delete [] x;
    	return result;
    }
};

臨交的時候我才發現題目裡面有這麼一句話:

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

由於要新申請陣列,所以我所需的額外空間是O(n)級別而非O(1)常量級。

試著交了一下,居然過了,但還是想試試有沒有符合要求的解法。

 

就地修改交換法

既然所開闢新陣列的大小恰恰與給出的元素一致,那為什麼不在原來的基礎上修改呢?

class Solution
{
public:
    int firstMissingPositive(vector<int>& nums) {
    	int n = nums.size();
        for(int i = 0; i < n; ++ i)
            while(nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i])
                swap(nums[i], nums[nums[i] - 1]);
        
        for(int i = 0; i < n; ++ i)
            if(nums[i] != i + 1)
                return i + 1;
        
        return n + 1;
    }
};