当前位置: 首页 > news >正文

【LeetCode刷题】缺失的第一个正数

给你一个未排序的整数数组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 <=
  • -231 <= nums[i] <=

解题思路

要在 O (n) 时间复杂度和常数级额外空间内解决问题,核心思路是原地哈希(标记)

  1. 范围确定:缺失的最小正整数一定在[1, n+1]范围内(n 为数组长度)。例如数组长度为 3,若 1、2、3 都存在则返回 4,否则返回缺失的最小数。
  2. 过滤无效值:将数组中所有≤0 或 > n 的数替换为n+1(这些数不可能是目标,替换后不干扰后续标记)。
  3. 标记存在的数:遍历数组,对每个元素x(取绝对值),若x ≤ n,则将数组第x-1位标记为负数(表示x这个数存在)。
  4. 查找缺失值:遍历数组,第一个正数的位置i+1就是缺失的最小正整数;若全为负数,说明 1~n 都存在,返回n+1

示例验证

示例 1:输入nums = [1,2,0]
  1. 过滤无效值:0 替换为 4 →[1,2,4]
  2. 标记存在的数:
    • x=1 → nums[0] = -1;
    • x=2 → nums[1] = -2;
    • x=4(>3)→ 不处理;数组变为[-1,-2,4]
  3. 遍历找正数:索引 2 是第一个正数,返回2+1=3(符合预期)。
示例 2:输入nums = [3,4,-1,1]
  1. 过滤无效值:-1 替换为 5,4 替换为 5 →[3,5,5,1]
  2. 标记存在的数:
    • x=3 → nums[2] = -5;
    • x=5(>4)→ 不处理;
    • x=5(>4)→ 不处理;
    • x=1 → nums [0] = -3;数组变为[-3,5,-5,1]
  3. 遍历找正数:索引 1 是第一个正数,返回1+1=2(符合预期)。
示例 3:输入nums = [7,8,9,11,12]
  1. 过滤无效值:所有数 > 5,替换为 6 →[6,6,6,6,6]
  2. 标记存在的数:所有 x=6(>5)→ 不处理,数组仍为[6,6,6,6,6]
  3. 遍历找正数:索引 0 是第一个正数,返回0+1=1(符合预期)。

核心优势

  • 时间复杂度 O (n):仅三次线性遍历,无嵌套操作;
  • 空间复杂度 O (1):仅使用常数级临时变量,原地修改数组;
  • 鲁棒性:处理了负数、重复值、超大数等边界场景,适配题目 10⁵级别的数组长度。

Python代码:

from typing import List class Solution: def firstMissingPositive(self, nums: List[int]) -> int: n = len(nums) # 过滤无效值 for i in range(n): if nums[i] <= 0 or nums[i] > n: nums[i] = n + 1 # 标记存在的数 for i in range(n): x = abs(nums[i]) if x <= n: nums[x - 1] = -abs(nums[x - 1]) # 查找缺失值 for i in range(n): if nums[i] > 0: return i + 1 return n + 1 # 测试用例 if __name__ == "__main__": solution = Solution() # 示例1 nums1 = [1,2,0] print(f"示例1输入: {nums1}") print(f"示例1输出: {solution.firstMissingPositive(nums1)}") # 示例2 nums2 = [3,4,-1,1] print(f"示例2输入: {nums2}") print(f"示例2输出: {solution.firstMissingPositive(nums2)}") # 示例3 nums3 = [7,8,9,11,12] print(f"示例3输入: {nums3}") print(f"示例3输出: {solution.firstMissingPositive(nums3)}") # 边界用例:1~n都存在 nums4 = [1,2,3,4] print(f"示例4输入: {nums4}") print(f"示例4输出: {solution.firstMissingPositive(nums4)}") # 边界用例:空值/重复值 nums5 = [2,2,2] print(f"示例5输入: {nums5}") print(f"示例5输出: {solution.firstMissingPositive(nums5)}")

LeetCode提交代码:

from typing import List class Solution: def firstMissingPositive(self, nums: List[int]) -> int: n = len(nums) # 步骤1:过滤无效值(≤0 或 >n的数替换为n+1,不干扰后续标记) for i in range(n): if nums[i] <= 0 or nums[i] > n: nums[i] = n + 1 # 步骤2:标记存在的正整数(用负数标记,表示对应数存在) for i in range(n): x = abs(nums[i]) # 取绝对值,避免已标记的负数干扰 if x <= n: # 仅处理1~n范围内的数 nums[x - 1] = -abs(nums[x - 1]) # 标记为负数(重复标记不影响) # 步骤3:查找第一个未标记的位置(正数),返回i+1 for i in range(n): if nums[i] > 0: return i + 1 # 所有1~n都存在,返回n+1 return n + 1

程序运行结果如下:

示例1输入: [1, 2, 0] 示例1输出: 3 示例2输入: [3, 4, -1, 1] 示例2输出: 2 示例3输入: [7, 8, 9, 11, 12] 示例3输出: 1 示例4输入: [1, 2, 3, 4] 示例4输出: 5 示例5输入: [2, 2, 2] 示例5输出: 1

总结

本文提出了一种在O(n)时间复杂度和常数空间内寻找数组中缺失最小正整数的算法。核心思路是通过原地哈希标记:首先过滤无效值(≤0或>n的数),然后利用数组索引标记存在的正整数(1~n),最后扫描数组找到第一个未被标记的位置。该方法高效处理了各种边界情况(负数、重复值、超大数等),并通过三个线性遍历实现最优复杂度。Python实现验证了算法的正确性,适用于LeetCode等编程挑战。

http://www.cnnetsun.cn/news/28009.html

相关文章:

  • WebRTC 是什么?能做什么?(概览篇)
  • Dubbo学习(三):深入 Remoting
  • AI设计新突破:QWEN溶图LoRA模型助力品牌视觉创作升级
  • 突破实时视频生成瓶颈:Krea Realtime 14B模型革新文本到视频技术
  • 【项目实战】Vercel 是一个让你的网站“瞬间上线”的云平台。Vercel 现在确实是技术圈的“当红炸子鸡”,尤其是在个人博客和前端开发领域。
  • Day28~实现strlen、strcpy、strncpy、strcat、strncat
  • 空洞骑士模组管理大师课:5个关键技巧让Scarab成为你的游戏管家
  • 实用方法:轻松实现NCM文件格式转换的完整解析
  • C++课后习题训练记录Day49
  • LeetCode 189. 旋转数组 | 三步反转最优解全拆解
  • downkyi视频下载:告别卡顿与画质损失的终极解决方案
  • 教你如何玩转DPDK开发中的KNI与内核交互,让网络速度翻倍!
  • Openresty驱动下的高性能Web网关实战
  • 百度网盘下载工具终极指南:快速突破限速的完整教程
  • C语言实现hashmap(附带源码)
  • jsonnet介绍和使用
  • 喜马拉雅音频数据采集:API接口分析与加密音频链接解密实战
  • 角色影像生成新纪元:Pony V7-Base引领AI创作革命
  • 论文格式修改排名:9大平台+在线一键优化
  • 论文写作效率低?十大AI生成平台,AIGC降重+赶due不熬夜
  • 文献引用规范考核要点解析与实践指南
  • 文献综述写作期末指南:方法、结构与常见问题解析
  • 期末文献研究论文的撰写方法与实践路径探讨
  • 基于 HID 协议的扩展功能指令定义方案
  • 模拟IC设计:集成电路与运算放大器大观
  • 6、Oracle数据库管理:文件与目录操作全解析
  • 12、Oracle数据库Linux服务器软件管理全攻略
  • 某聘新版AST解混淆(青春版)
  • 基于Spring Boot框架和vue的的诗词鉴赏与交流网站的设计与实现_96fdvu1s
  • 基于模型预测算法的混合储能微电网双层能量管理系统研究(Matlab代码实现)