【原地哈希】LeetCode - 41.缺失的第一个正数

题目描述

题目链接
在这里插入图片描述

解法

首先想到的是哈希,本题哈希的思路如下:

假设原始数组为 A。先构造一个临时数组 tmp,初始化为 0,大小为A.size(). 遍历 A,把 A[i] 复制到 tmp[A[i]-1] 的位置。如果 A[i] - 1 超过了 tmp 的范围,就直接扔掉。如此一来,tmp[0…size) 中就保存了一部分 A 的值。然后从位置 0 开始检查 tmp,如果发现该位置的值和索引号不匹配,就说明找到了缺失的数了

但是题目要求严格的空间复杂度了,那就原地哈希,准确的说是原地置换的思路和算法,但我把它和哈希放一块是因为这题很容易一上来就想哈希,那在哈希满足不了题目要求时,往往可以也用置换的办法吧我觉得。

或者理解为,原地置换思想就相当于我们自己编写哈希函数,这个哈希函数的规则就是数值为 i 的数映射到下标为 i - 1 的位置。放张图以便理解
在这里插入图片描述

注意理解代码 nums[nums[i] - 1] != nums[i] 的作用。这是因为nums[i]应该呆的位置被跟它重复的值占用了,这种情况直接跳过就行,不需要再置换。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int len = nums.size();
        for(int i = 0; i < len; i++)
        {
            while(nums[i] > 0 && nums[i] <= len && nums[i] != i+1 && nums[nums[i]-1] != nums[i])
             swap(nums, nums[i]-1, i);
        }
        for(int i = 0; i < len; i++)
         if(nums[i] != i+1)
          return i + 1;
        return len + 1;
    }
    void swap(vector<int>& nums, int i, int j)
    {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
};

原地置换的相同思路和算法在 【原地哈希】剑指Offer 03.数组中重复的数字 中也有

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值