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)的時間複雜度以及常數級的空間。
那麼自然不能排序,也不能申請額外非常數級的空間, 那就只能在原數組上操作了
一開始的想法時,遍歷的時候,將Num[i]放在其正確的位置上,放完之後再去歷一次,查到第一個不對應的下標,即是答案。
但是思路有問題:
1.每次遍歷就把 nums[i] 和 nums[num[i]] 互換, 非正數 和 超過數組長度的 不處理。然而這樣子,後面的數被換到前面之後,就不會再被遍歷到,造成缺漏的情況,卡住了。
2.每次遍歷的時候,把nums[i]放在nums[nums[i]]的位置,將nums[nums[i]]先取出到tmp,然後直接對tmp進行重複操作放在正確的位置。但是想想這樣就覺得很麻煩。
正確思路:
交換數組元素,使得數組中第i位存放數值(i+1)。最後遍歷數組,尋找第一個不符合此要求的元素,返回其下標。整個過程需要遍歷兩次數組,複雜度爲O(n)。
正確思路確實就是一開始的第一種思路,既然會缺漏,那麼對當前位置繼續操作就行了,直到當前位置的value不滿足條件了。所以通常思路都很接近了,然後自己放棄了…….解決
public class first_missing_positive {
public int firstMissingPositive(int[] nums) {
int len = nums.length;
int swap = 0;
//之所以對於元素i的正確位置爲 index = i-1.
//是因爲如果一個數組都是正數,那最長只能到i-1.
for (int i = 0 ; i < len ; i++)
{
//nums[i] != nums[nums[i]-1]
//表示如果nums[i]正確位置下的元素已經正確,那麼也略過 不然會陷入死循環。
while (nums[i] > 0 && nums[i] < len
&& nums[i] != nums[nums[i]-1])
{
swap = nums[nums[i]-1];
nums[nums[i] - 1] = nums[i];
nums[i] = swap;
}
}
for (int i = 0 ; i < len ; i++)
if (nums[i]!=i+1)
return i+1;
return len+1;
}
}