1. 程式人生 > 實用技巧 >LeetCode41 缺失的第一個正數

LeetCode41 缺失的第一個正數

給你一個未排序的整數陣列,請你找出其中沒有出現的最小的正整數。

第一種方法,置換,把每個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 };