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 };

 

posted @ 2020-07-24 17:57  __rookie  阅读(166)  评论(0编辑  收藏  举报