力扣41缺失的第一个正数(哈希表法)

41. 缺失的第一个正数 - 力扣(LeetCode)

为什么用哈希表:

哈希表是一个可以支持快速查找 的数据结构:给定一个元素,我们可以在 O(1) 的时间查找该元素是否在哈希表中

实现参考思路:

将数组所有的数放入哈希表,随后从 1 开始依次枚举正整数,并判断其是否在哈希表中。

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

Ⅰ、筛选

所以我们先把所有不可能是答案的:负数、0、先筛去(即放到答案范围之外,即N+1后面)

怎么筛?

0、负数一律变成N+1(第一轮筛选)eg.1、0 、5=>1、4、5

java 复制代码
for (int i = 0; i < n; ++i) {
            if (nums[i] <= 0) {
                nums[i] = n + 1;
            }
        }

Ⅱ、标记

符合要求 的数字前面的那一个数字取为负数,当作标记符号来用**×**

原理解:符合要求的数字前面那一个数字取负数标记 ❌

实际原理:拿当前读到的数字本身 作为下标,数字-1得到目标位置,把这个目标位置的值标记成负数 ✅(当作标记符号)

num ∈ 1,n:把 nums[num-1] 置负(打标记,表示 num 存在)

java 复制代码
for (int i = 0; i < n; ++i) {
            int num = Math.abs(nums[i]);//① 取绝对值,防止已经被标记成负数
            if (num <= n) {
                nums[num - 1] = -Math.abs(nums[num - 1]);//②
            }
        }

第二轮循环代码中两个取绝对值的位置分别有什么用:

①读数据时,消除前面循环(可能)留下的负标记,拿到原始数字

②打标记时,先消除目标位置已有的负号,再强制置负,避免重复数字反复翻转正负

Ⅲ、根据标记找答案

从左往右遍历数组,找第一个 >0 的位置,下标 i,答案就是 i+1

java 复制代码
for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }

这不是找到的第一个出现的正数?本题目不是求第一个缺失的正数?

注意了这里找的是numsi > 0而不是< 0,是没有标注的位置 ,说明数字 i+1 从来没有在数组里出现过
否则(即从第1个到第n个都不符合)返回N+1

java 复制代码
     return n + 1;

完整代码回顾

java 复制代码
class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            if (nums[i] <= 0) {
                nums[i] = n + 1;
            }
        }
        for (int i = 0; i < n; ++i) {
            int num = Math.abs(nums[i]);
            if (num <= n) {
                nums[num - 1] = -Math.abs(nums[num - 1]);
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }
}
相关推荐
飞Link4 小时前
什么是 AirSim?一文读懂无人机仿真平台
python·算法·无人机
一去不复返的通信er7 小时前
贪心算法-合并区间(LeetCode 56)
算法·leetcode·贪心算法
Shaoshing7 小时前
LeetCode100 49. 字母异位词分组
java·算法
YFJ_mily8 小时前
第二届区块链技术与基础模型国际学术会议(BTFM2027)
算法·区块链·能源·智能系统·rdlink研发家·机器人自动化
汤姆宝库8 小时前
收官深拆:第一性原理、产业电网与未来推演
大数据·人工智能·算法
moshuying10 小时前
块扩散 + GDN 改造:Clover 把「并行生成」塞进了 Agent 的长上下文里
前端·算法
没落之王10 小时前
历史系统建模:宋初太祖太宗「再立天庭」秩序重构推演
人工智能·算法·重构
INGNIGHT11 小时前
91 · 最小调整代价(序列dp)
数据结构·算法·leetcode
moshuying11 小时前
扩散模型开始写代码、开网页了:350 亿参数,速度比 Jev 快一倍
前端·算法