每日一題,防止癡呆 = =
一、題目大意
給你一個未排序的整數數組,請你找出其中沒有出現的最小的正整數。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/first-missing-positive
二、題目思路以及AC代碼
思路:
這題標定的難度是困難,但我感覺思路並不是很難想到。
首先第一個想法肯定是可以用哈希表做的,或者標記數組,這樣我們只需要用O(N)額外的空間就可以達到時間複雜度爲O(N)的要求了。
題目明確要求不能用額外的空間,而且時間複雜度要求爲O(N),這也是標記難度爲困難的原因。但是我們可以順着這個思路,再結合題目特點考慮一下。首先要求最小的沒有出現的正整數,對於長度爲N的數組來說,結果只能是 1 ~ N + 1中的一個數,這樣的話,我們其實只需要知道數組中 1 ~ N 這些數出現的情況就可以了,而要知道 1 ~ N 這些數出現的情況,只需要一個長度爲 N 的標記數組即可,題目正好是一個長度爲N的空間,那麼我們就想到可以裏用原數組空間去統計數組中 1 ~ N 這些數的出現情況。
具體操作我舉個例子解釋一下:
原數組: [-1,4,2,1,9,10],長度爲 6
首先遍歷 -1,因爲 -1 <= 0 跳過;
然後遍歷 4,因爲 0 < 4 <= 6,所以暫存4的值;
然後找到nums[4 - 1]的位置,存儲的是 1,因爲 0 < 1 <= 6,所以暫存1的值,將1位置處改爲 -MAX_INT,原數組變爲 [-1, 4, 2, -MAX_INT, 9, 10];
然後找到nums[1 - 1]的位置,存儲的是-1,因爲 -1 <= 0,所以不存 -1 的值,將-1位置處改爲-MAX_INT,原數組變爲[-MAX_INT, 4, 2, -MAX_INT, 9, 10];
繼續遍歷2,因爲 0 < 2 <= 6,所以暫存2的值;
然後找到nums[2 - 1]的位置,存儲的是 4,因爲 0 < 4 <= 6,所以暫存4的值,將4位置處改爲-MAX_INT,原數組變爲[-MAX_INT, -MAX_INT, 2, -MAX_INT, 9, 10];
然後找到nums[4 - 1]的位置,存儲的是-MAX_INT,則跳過;
繼續遍歷-MAX_INT,跳過;
繼續遍歷9,由於 9 > 6,跳過;
繼續遍歷10,由於 10 > 6,跳過;
最終得到結果數組爲 [-MAX_INT, -MAX_INT, 2, -MAX_INT, 9, 10],其中 0,1,3 索引處爲-MAX_INT,正好標記了1,2,4三個元素,然後在遍歷找到第一個不爲-MAX_INT的元素即是結果。
但是這樣實現有一個小問題,就是標記元素-MAX_INT要找一個在原數組中沒有出現的數字才能得到正確的結果。
AC代碼
#define MAX_INT -2147483648
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n_size = nums.size();
for (int i=0;i<n_size;i++) {
if (nums[i] <= 0 || nums[i] > n_size) continue;
int idx = nums[i] - 1;
int temp = nums[idx];
nums[idx] = MAX_INT;
idx = temp;
while (idx > 0 && idx <= n_size) {
temp = nums[idx - 1];
nums[idx - 1] = MAX_INT;
idx = temp;
}
}
for (int i=0;i<n_size;i++) {
if (nums[i] != MAX_INT) return i + 1;
}
return n_size + 1;
}
};
如果有問題,歡迎大家指正!!!