缺失的正整數,我自己解出來了,和官方題解思路不一樣
題目描述:
給你一個未排序的整數數組,請你找出其中沒有出現的最小的正整數。
示例 1
輸入: [1,2,0]
輸出: 3
示例 2:
輸入: [3,4,-1,1]
輸出: 2
示例 3:
輸入: [7,8,9,11,12]
輸出: 1
提示:
你的算法的時間複雜度應爲O(n),並且只能使用常數級別的額外空間。
我的思路很直接,排序之後,重複的去重,剩下的第一個元素與1比較,第二個元素與2比較,第三個元素與3比較,依次類推,只要出現小於的情況,直接返回結果。
public int firstMissingPositive(int[] nums) {
if(null == nums) return 1;
Arrays.sort(nums); // 排序
int compare = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] <= 0) continue;
if(i > 0 && nums[i-1] == nums[i]) continue; // 重複的數字直接略過
compare++;
if(compare < nums[i]) return compare;
}
// 數組中出現的正數,排序後恰好是遞增的,那就返回compare+1
return compare+1;
}
我的解法,沒什麼特別之處,時間複雜度是O(n),空間複雜度是常數級別的,符合題目要求。
下面看下官方的題解,思路很巧妙,我壓根就想不到。
若數組中有 n 個元素,且從1開始遞增的,那答案一定是n+1,否則答案一定是大於0小於n,
第一步,把數組中的元素,小於0的,大於n+1的都替換爲n+1;
第二步,對數組下標作文章,遍歷數組,比如第一個元素值是5,那就把第5個元素設置爲負數
第三步,再次遍歷數組,第一個大於0的數,說明沒有給它做標記的,即那個數字沒出現。
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
if (nums[i] <= 0) {
nums[i] = n + 1;
}
}
for (int i = 0; i < n; ++i) {
int num = Math.abs(nums[i]);
if (num <= n) {
nums[num - 1] = -Math.abs(nums[num - 1]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
官方的題解確實很優雅,我真的想不到。我的解法,也還行,畢竟是符合題目要求的。