LeetCode---41. 缺失的第一个正数(将数组视为哈希表,把每个元素都放在其应该在的位置上)

必备知识

C+±–库函数swap的用法

由于题目要求我们「只能使用常数级别的空间」,而要找的数一定在 [1, N + 1] 左闭右闭(这里 N 是数组的长度)这个区间里。因此,我们可以就把原始的数组当做哈希表来使用。事实上,哈希表其实本身也是一个数组;
我们要找的数就在 [1, N + 1] 里,最后 N + 1 这个元素我们不用找。因为在前面的 N 个元素都找不到的情况下,我们才返回 N + 1;
那么,我们可以采取这样的思路:就把 1 这个数放到下标为 0 的位置, 2 这个数放到下标为 1 的位置,按照这种思路整理一遍数组。然后我们再遍历一次数组,第 1 个遇到的它的值不等于下标的那个数,就是我们要找的缺失的第一个正数。
这个思想就相当于我们自己编写哈希函数,这个哈希函数的规则特别简单,那就是数值为 i 的数映射到下标为 i - 1 的位置。

在这里插入图片描述

示例代码

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int len=nums.size();
        //我们要找的数就在 [1, N + 1] 里,最后 N + 1 这个元素我们不用找。
        //因为在前面的 N 个元素都找不到的情况下,我们才返回 N + 1;
        //就把 1 这个数放到下标为 0 的位置, 2 这个数放到下标为 1 的位置
        //按照这种思路整理一遍数组。(通过交换的方式进行放置,否则会覆盖掉一些元素)
        for(int i=0;i<len;i++){
            //while 循环不会每一次都把数组里面的所有元素都看一遍。如果有一些元素在这一次的循环中被交换到了它们应该在的位置,那么在后续的遍历中,
            //由于它们已经在正确的位置上了,代码再执行到它们的时候,就会被跳过。
            while(nums[i]!=i+1){
                //这里不直接进行返回是因为只有到最后才能知道结果
                //nums[i] == nums[nums[i] - 1]防止出现死循环
                if(nums[i]<=0||nums[i]>len||nums[i] == nums[nums[i] - 1]){
                    break;
                }
                //他要放的实际位置,将nums[i] 放置到对应位置上[1,2,3...]
                //进行交换操作
                swap(nums[i],nums[nums[i]-1]);
            }
        }

        for(int i=0;i<len;i++){
            if(nums[i]!=i+1){
                return i+1;
            }
        }
        return len+1;        
    }
};

效果展示

在这里插入图片描述

相似题目

442. 数组中重复的数据
448. 找到所有数组中消失的数字

  • 21
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank---7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值