1. 程式人生 > >Leetcode First Missing Positive 三個思路

Leetcode First Missing Positive 三個思路

First Missing Positive

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

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

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

 這條題目雖然簡單,但是思路還是很多的,可以開拓一下思路。

下面三種思路都是O(n)時間複雜度,測試執行時間基本上都沒區別:

1 排序之後查詢

2 把出現的數值放到與下標一致的位置,再判斷什麼位置最先出現不連續的數值,就是答案了。

3 和2差不多,把出現過的數值的下標位置做好標識,如果沒有出現過的陣列的下標就沒有標識,那麼這個就是答案。

 第一個思路最簡單了:

class Solution {
public:
	int firstMissingPositive(int A[], int n) {
		sort(A, A+n);
		int res = 0;
		int i = 0;
		while (i<n && A[i]<=0) i++;
		for (; i < n; i++)
		{//注意:一看到序列就應該馬上反應問題:是否有重複元素???
			if (i>0 && A[i] == A[i-1]) continue;
			if (A[i] - res != 1) return res+1;
			else res = A[i];
		}
		return res+1;
	}
};


 下面是參考了leetcode上的程式,思路2:

int firstMissingPositive2(int A[], int n) {
		for (int i=0; i<n; i++)
		{
			if (A[i] > 0 && A[i] < n)
			{
				//if (A[i]-1 != i && A[A[i]-1] != A[i])不用那麼多條件就可以了。
				//因為只要是已經到位了的元素即:A[i]-1==i了,那麼判斷如果有重複元素
				//兩個位置交換就最好考慮好兩個位置出現的可能情況。考慮問題全面,兩個條件都考慮好。
				//update:增加i!=A[i]表示i位置沒到位,A[A[i]-1] != A[i]表示A[i]-1位置沒到位,兩個位置都判斷也很好的。
				if (A[A[i]-1] != A[i])
				{
					swap(A[A[i]-1], A[i]);
					i--;
				}
			}
		}

		for (int j=0; j<n; ++j)
			if (A[j]-1 != j)
				return j+1;

		return n+1; 
	}

也是思路二,不過上面的是處理下標從1開始,下面的程式是處理下標從0開始的:

int firstMissingPositive3(int A[], int n) {
		int i = 0;
		while (i < n) {
			//逐個把A[i]放到A[i]位置的思想
			//1:找到一個A[i]是在0到n範圍的就放到相應位置
			//2:沒找到的直接跳過
			//簡單來說:就是把數字與下標對應起來
			if (A[i] >= 0 && A[i] < n && A[A[i]] != A[i])
				swap(A[i], A[A[i]]);
			else i++;
		}
		int k = 1;
		while (k < n && A[k] == k) k++;
		if (n == 0 || k < n) return k;
		else return A[0] == k ? k + 1 : k;
	}

思路三,好像稍微複雜一點。

int firstMissingPositive4(int A[], int n) {
		if(n <= 0)
			return 1;
		int intOutOfRange = n + 2;
		//first run, turn every negetive value into an impossible positive value
		//make every value in A is positive
		for(int i = 0 ; i < n ; ++ i) {
			if(A[i] <= 0)
				A[i] = intOutOfRange;
		}
		//second run, make A[] as a hash table, A[i] indicate the presence of i + 1
		//the way is that, if k in [1,n] is in A[], then turn A[k -1] to negetive
		for(int i = 0 ; i < n ; ++i) {
			int ai = A[i];
			int absi = abs(ai);
			if(absi <= n)
				A[absi-1] = -abs(A[absi-1]);
		}
		//third run, if A[i] is positive, from step 2, we know that i + 1 is missing.
		for(int i = 0 ; i < n ; ++i) {
			if(A[i] > 0)
				return i + 1;
		}
		//all int from 1 to n is present, then return n + 1
		return n+1;
	}

簡單:

//2014-1-27 update
	int firstMissingPositive(int A[], int n) 
	{
		for (int i = 0; i < n; )
		{
			if (0<A[i]&& A[i]<n && A[i] != i && A[A[i]] != A[i]) 
				swap(A[i], A[A[i]]);
			else i++;
		}
		for (int i = 1; i < n; i++) 
			if (A[i] != i) return i;

		return A[0] == n? n+1:n;
	}