每日一题:缺失的第一个正数

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3
解释:范围 [1,2] 中的数字都在数组中。

示例 2:

输入:nums = [3,4,-1,1]
输出:2
解释:1 在数组中,但 2 没有。

示例 3:

输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正数 1 没有出现。

提示:

  • 1 <= nums.length <= 105
  • -2^31 <= nums[i] <= 2^31 - 1

如果没有时间、空间复杂度要求,那么可以使用哈希表存储数组中出现的每一个元素,然后从正整数1开始枚举,直到找到不在表内的正整数即为所求。

但由于限制了时间复杂度O(n),使用常数级别的额外空间。也就是要求每个元素只遍历一次,且不能创建长度为n的数据结构。

所以使用考虑使用原地哈希。将哈希表存储在要哈希的数组中。

对于一个长度为 N 的数组,其没有出现的最小正整数只能在 [1,N+1] 中。

因此我们想要构建的目标数组形式如下:

  • 以[3,-1,4,1]为例。需要通过变换,让它变成[1,-1,3,4]的形式。
  • 考虑下标,nums[i]存储的值,就是i+1。而转换后第一个不满足这个条件的位置,就是缺少的第一个正整数。

第一步:i = 0,nums[i] = 3 != i+1,因此需要将nums[i]的值与nums[nums[i] - 1]交换。

第二步,i 仍然为0,因为当前位置没有被交换为1。继续交换。

此时,i = 0位置上的数已经符合要求了,i++。

这里如果起始数组里没有1这个数字,也就是说缺失的就是1会发生什么?

--- 在经过多次循环交换后,要么这个位置的值小于0,要么大于n+1,要么像后文所述,出现了重复数字。

所以要注意循环跳出条件。

这个例子中,到这一步其实就已经完成交换了,接下来就是遍历完所有的i,结束。

代码:

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 && nums[nums[i] - 1] != nums[i]){
                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;
    }
};

额外关注下nums[nums[i] - 1] != nums[i]这个循环跳出条件。

由于题目不保证一个数只出现一次,如果交换的两个数恰好相等,那么就会陷入死循环,所以加入这个条件跳出循环。

相关推荐

  1. 第一正数 - LeetCode 热 17

    2024-04-14 19:16:03       16 阅读
  2. 面试算法-49-第一正数

    2024-04-14 19:16:03       19 阅读
  3. Leetcode 41. 第一正数

    2024-04-14 19:16:03       18 阅读
  4. leetcode_41.第一正数

    2024-04-14 19:16:03       9 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-14 19:16:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-14 19:16:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-14 19:16:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-14 19:16:03       20 阅读

热门阅读

  1. 线程池的参数 以及实现

    2024-04-14 19:16:03       16 阅读
  2. 【接着模拟赛】2024.4.14

    2024-04-14 19:16:03       17 阅读
  3. 239. 滑动窗口最大值

    2024-04-14 19:16:03       14 阅读
  4. win10清华源按装OPENCV和其他软件

    2024-04-14 19:16:03       16 阅读
  5. Csharp_pta2

    2024-04-14 19:16:03       14 阅读
  6. 中文域名有必要注册吗?

    2024-04-14 19:16:03       14 阅读
  7. conda搭建与管理python环境

    2024-04-14 19:16:03       14 阅读