LeetCode-41 缺失的第一個正整數
阿新 • • 發佈:2022-03-29
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/first-missing-positive
題目描述
給你一個未排序的整數陣列 nums ,請你找出其中沒有出現的最小的正整數。
請你實現時間複雜度為 O(n) 並且只使用常數級別額外空間的解決方案。
示例 1:
輸入:nums = [1,2,0]
輸出:3
示例 2:
輸入:nums = [3,4,-1,1]
輸出:2
示例 3:
輸入:nums = [7,8,9,11,12]
輸出:1
提示:
1 <= nums.length <= 5 * 105
-231 <= nums[i] <= 231
解題思路
理論上並不存在時間複雜度為O(n) 空間複雜度為 O(1)的演算法來做這道題,所以需要藉助題目提供的nums來解,nums的範圍為n,那麼可以利用nums來判斷1-n中是否有數字出現,如果沒有,那麼最小正整數為n+1,否則就是第一個缺失的數字。
一個思路是利用負號來記錄1-n中數字是否出現過,先將所有負數變成n+1,然後遍歷,如果數字x出現就將數字x對應的下標x-1的值設定為負數,等結束後第一個正數的下標加一就是缺失的數字。
另一個思路是重置歸位,將1-n中的數字重置到nums對應的位置上並且繼續重置被交換的數,那麼第一個錯位的數字就是缺失的數字。注意由於nums中數字可能相同,所以交換的雙方相等就可以結束交換繼續遍歷。
程式碼展示
負號做標記
class Solution { public: int firstMissingPositive(vector<int>& nums) { int n = nums.size(); for(int i = 0; i < n; i++) { if(nums[i] <= 0) nums[i] = n + 1; } for(int i = 0; i < n; i++) {if(abs(nums[i]) < n + 1) nums[abs(nums[i]) - 1] = nums[abs(nums[i]) - 1] < 0 ? nums[abs(nums[i]) - 1] : -1 * nums[abs(nums[i]) - 1]; } for(int i = 0; i < n; i++) if(nums[i] > 0) return i + 1; return n + 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 + 1 && nums[i] != nums[nums[i] - 1]) { 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; } };
執行結果