LeetCode41 缺失的第一個正數
阿新 • • 發佈:2020-07-24
給你一個未排序的整數陣列,請你找出其中沒有出現的最小的正整數。
第一種方法,置換,把每個x放到x-1的位置上(減一是因為這裡是說正整數,如果不減一會沒法處理到0號位置的數)。這樣做完之後重新遍歷,第一個不等於位置x+1的數就是答案。
1 class Solution { 2 public: 3 int firstMissingPositive(vector<int>& nums) { 4 int n = nums.size(); 5 for (int i = 0; i < n; ++i) { 6 while(nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { 7 swap(nums[nums[i] - 1], nums[i]); 8 } 9 } 10 for (int i = 0; i < n; ++i) { 11 if (nums[i] != i + 1) { 12 return i + 1; 13 }14 } 15 return n + 1; 16 } 17 }; 18 19 作者:LeetCode-Solution 20 連結:https://leetcode-cn.com/problems/first-missing-positive/solution/que-shi-de-di-yi-ge-zheng-shu-by-leetcode-solution/ 21 來源:力扣(LeetCode) 22 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
第二種,原地雜湊。雜湊表可以直接處理這個問題,但是需要O(n)的額外空間。我們可以直接原地建立雜湊表。因為答案只可能在(1,n+1)的範圍內,所以可以原地雜湊。先把所有非正數變為n+1,然後遍歷陣列,遇到任何一個小於n+1的數,假如為x,就把x-1的位置的數置為負的。操作完畢後最後遍歷陣列,遇到的第一個不是負數的位置x,就返回x+1。如果沒有就返回n+1。
需要注意在第二次遍歷的時候,判斷出數字不是n+1後,應該把陣列先取出來取絕對值,否則會造成訪問負數位置,導致越界。
1 class Solution { 2 public: 3 int firstMissingPositive(vector<int>& nums) { 4 int n = nums.size(); 5 if (!n) 6 return 1; 7 for (int i = 0; i < n; ++i) 8 if (nums[i] <= 0) 9 nums[i] = n+1; 10 11 for (int i = 0; i < n; ++i) { 12 if (abs(nums[i]) != n+1) { 13 int tempnum=abs(nums[i]); 14 if (tempnum - 1 < n && nums[tempnum - 1] > 0) 15 nums[tempnum - 1] = -nums[tempnum - 1]; 16 } 17 } 18 for (int i = 0; i < n; ++i) { 19 if (nums[i] > 0) 20 return i + 1; 21 } 22 return n+1; 23 } 24 };