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

力扣(LeetCode)100题:41.缺失的第一个正数

41.缺失的第一个正数

我的题解:排序+遍历

class Solution:def firstMissingPositive(self, nums: List[int]) -> int:nums.sort()j=1for i in range(len(nums)-1):if nums[i]<=0 or nums[i]==nums[i+1]:continueif nums[i]==j:j+=1else:return jif nums[len(nums)-1]==j:j+=1else:return jreturn j

官方题解

一、哈希表

✅ 解法核心思想:原地标记法(利用数组下标作为“哈希表”)

我们将数组本身当作一个隐式的哈希表:

  • 如果数字 x(1 ≤ x ≤ n)存在,则让 nums[x - 1] 变为负数(作为标记)
  • 最后遍历数组,第一个仍为正数的位置 i,说明 i+1 没有出现 → 即答案

🔍 逐行注释与解释

class Solution:def firstMissingPositive(self, nums: List[int]) -> int:n = len(nums)# 第一步:把所有非正数(≤0)替换为一个“无关”的大数(n+1)# 因为我们只关心 1 到 n 的正整数(答案一定在 [1, n+1] 中)for i in range(n):if nums[i] <= 0:nums[i] = n + 1# 第二步:遍历数组,对每个在 [1, n] 范围内的数 x,# 将 nums[x - 1] 标记为负数(表示 x 已出现)for i in range(n):num = abs(nums[i])          # 取绝对值,因为可能已被标记为负if num <= n:                # 只处理 1 ~ n 的数nums[num - 1] = -abs(nums[num - 1])  # 标记位置 num-1 为负# 第三步:再次遍历,找第一个仍为正数的位置 i# 说明数字 i+1 没有出现过for i in range(n):if nums[i] > 0:return i + 1# 如果 1~n 都出现了,那么答案就是 n+1return n + 1

📌 为什么答案一定在 [1, n+1]

  • 数组长度为 n
  • 最理想情况:nums = [1, 2, 3, ..., n] → 缺失的是 n+1
  • 其他情况:至少有一个 1~n 中的数缺失 → 答案 ∈ [1, n]
  • 所以 答案 ∈ [1, n+1],无需考虑更大的数!

因此,我们可以安全地忽略所有 > n≤ 0 的数。


🧪 举例说明

示例 1:
nums = [3, 4, -1, 1]
n = 4

Step 1: 替换非正数
[3, 4, 5, 1] (-1 → 5)

Step 2: 标记出现的数

  • i=0: num=3 → 标记 index=2 → [3, 4, -5, 1]
  • i=1: num=4 → 标记 index=3 → [3, 4, -5, -1]
  • i=2: num=5(>4)→ 忽略
  • i=3: num=1 → 标记 index=0 → [-3, 4, -5, -1]

Step 3: 找第一个正数
→ index=1 是正数(4)→ 返回 1+1 = 2

示例 2:
nums = [1, 2, 0]
n = 3

→ Step1: [1,2,4]
→ Step2: 标记 1→index0, 2→index1, 4忽略 → [-1,-2,4]
→ Step3: index2 为正 → 返回 3

示例 3:
nums = [1, 2, 3]
n = 3

→ 全部标记为负:[-1,-2,-3]
→ 没有正数 → 返回 4

二、置换

✅ 核心思想(原地置换 / Cyclic Sort)

数组长度为 n,则答案必定在 [1, n+1] 范围内。
若数字 x(满足 1 ≤ x ≤ n)存在,则应将其放到下标 x - 1 的位置上。
最终遍历数组,第一个不满足 nums[i] == i + 1 的位置,其 i + 1 即为缺失的最小正整数。


🧩 代码解析

class Solution:def firstMissingPositive(self, nums: List[int]) -> int:n = len(nums)# 将每个合法正整数(1~n)放到它“应该在”的位置:nums[x-1] = xfor i in range(n):while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]:# 交换:把 nums[i] 放到正确位置,同时把原来那里的数换过来nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]# 找第一个“错位”的位置for i in range(n):if nums[i] != i + 1:return i + 1# 若 1~n 都在正确位置,则缺失的是 n+1return n + 1
http://www.dtcms.com/a/610246.html

相关文章:

  • 模考倒计时网页版
  • 【IP核 LOCKED】VIVADO IP核锁住的解决办法
  • 关于做网站的pptwordpress录入信息
  • 省直部门门户网站建设织梦做的的网站首页显示空白
  • 拆解LSTM:告别梯度消失,解锁序列数据的深度学习利器
  • 宁乡的网站建设建设网站常见问题
  • 【QML 与 C++ 类型系统深度融合:自定义 QML 类型、属性绑定底层原理及类型转换优化】
  • 大话Rust的前生今世
  • SpringBoot3配置文件
  • 电子商务网站建设的方法及流程图专业的餐饮网站建设
  • 泾川县建设局网站哈尔滨信息网
  • idea关闭自动编译
  • 静态页优秀网站石家庄关键词优化报价
  • 【Qt】QT的程序打包
  • 电子商务企业网站建设发展论文网站平台建设经费预算
  • 从系统到软件---架构设计的进阶之道
  • 【开题答辩过程】以《基于Vue的中国旅行系统的设计与实现》为例,不会开题答辩的可以进来看看
  • 网站策划技巧飞虹网架建设官方网站
  • ui设计师与网站编辑有什么关系指纹定制网站
  • Java 开发环境安装指南(五) | Git 安装
  • 云南省植保植检站网址动漫网站开发毕业设计
  • Deepin VNC 服务配置与 SSH 隧道安全访问配置指南
  • 企业网站建设怎么策划公司备案号查询平台官网
  • SpringCloud面试题(49道含答案)
  • 玄机-第八章 内存马分析-java02-shiro
  • 延安网站建设哪家专业wordpress主题底部
  • 递归、剪枝、回溯算法---全排列、子集问题(力扣.46,78)
  • JavaScript 对象
  • --- 多源bfs算法 01矩阵---
  • 绵阳做网站网站底部的备案信息