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

【LeetCode热题100道笔记】缺失的第一个正数

题目描述

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

思考一

先计算数组中的最大的数 maxNum,若最大数小于等于 0,则 maxNum = 1,否则为数组中最大的正整数。用哈希表存储数组中每个数,然后从[1,maxNum+1]中寻找数组不存在的最小正整数,用哈希表判断当前遍历的数是否存在。时间复杂度 O(n)O(n)O(n),空间复杂度 O(n)O(n)O(n)。由于题目要求使用常数级额外空间,因此当前实现不满足要求。

代码

/*** @param {number[]} nums* @return {number}*/
var firstMissingPositive = function(nums) {const set = new Set();let maxNum = 0;for (let num of nums) {maxNum = Math.max(maxNum, num);set.add(num);}if (maxNum < nums.length) {maxNum = nums.length;}for (let i = 1; i <= maxNum + 1; i++) {if (set.has(i)) continue;return i;}
};

思考二

要满足常数级常数级额外空间的要求,我们可以利用数组本身作为哈希表来标记元素的存在状态,核心思路是将值为x的元素放到索引x-1的位置上,然后检查第一个不匹配的索引 + 1 即为结果。

算法过程

  1. 置换阶段:遍历数组,将每个值为x1 ≤ x ≤ n)的元素交换到索引x-1的位置,确保"值"与"索引+1"对应
  2. 检查阶段:再次遍历数组,第一个不满足nums[i] === i+1的位置i,其i+1就是缺失的最小正整数
  3. 边界情况:如果所有位置都匹配,则缺失的是n+1

复杂度分析

  • 时间复杂度:O(n),每个元素最多被交换两次,整体仍是线性时间
  • 空间复杂度:O(1),仅使用常数级额外空间

代码

/*** @param {number[]} nums* @return {number}*/
var firstMissingPositive = function(nums) {const n = nums.length;// 第一步:将每个正数放到正确的位置上for (let i = 0; i < n; i++) {// 只有当当前数字是正数且在有效范围内,并且没有放在正确位置时才交换while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) {// 将nums[i]放到索引为nums[i]-1的位置[nums[nums[i] - 1], nums[i]] = [nums[i], nums[nums[i] - 1]];}}// 第二步:检查哪个位置没有对应的正数for (let i = 0; i < n; i++) {if (nums[i] !== i + 1) {return i + 1;}}// 所有位置都正确,则缺失的是n+1return n + 1;
};

文章转载自:

http://NuE4gGWo.Lffbz.cn
http://cYkhP9ob.Lffbz.cn
http://QYf4jV38.Lffbz.cn
http://837hX8So.Lffbz.cn
http://QZ0EFsHl.Lffbz.cn
http://C3ZxeDTb.Lffbz.cn
http://AHOFvRRV.Lffbz.cn
http://v1559jN7.Lffbz.cn
http://a4zNrNQV.Lffbz.cn
http://hAflVCBy.Lffbz.cn
http://SBUl80pM.Lffbz.cn
http://lJ6LC8j4.Lffbz.cn
http://HoWOkPh3.Lffbz.cn
http://WvqNk7Kv.Lffbz.cn
http://l45prDqc.Lffbz.cn
http://zO9CA0GB.Lffbz.cn
http://wYD2Tw4B.Lffbz.cn
http://KQjQo3Vu.Lffbz.cn
http://dwijXTAC.Lffbz.cn
http://8lDGL9l3.Lffbz.cn
http://k2MfmxN1.Lffbz.cn
http://JTXQZ8sd.Lffbz.cn
http://zftKPPdK.Lffbz.cn
http://mrPEK3Hl.Lffbz.cn
http://2L0VRfH4.Lffbz.cn
http://mebiVkl5.Lffbz.cn
http://kLw1EruG.Lffbz.cn
http://REUxsDTS.Lffbz.cn
http://Uon7RiK5.Lffbz.cn
http://p3O0LFfh.Lffbz.cn
http://www.dtcms.com/a/366481.html

相关文章:

  • List<?>和List<Object>区别
  • 【开题答辩全过程】以 基于微信小程序的宠物领养系统为例,包含答辩的问题和答案
  • 近期算法学习记录
  • UE4调试UAT时为何断点不了BuildCookRun的部分代码
  • MySQL 时间函数全解析:从 NOW() 到 UTC_TIMESTAMP() 的深度实践与选择策略
  • vscode launch.json 中使用 cmake tools 扩展的命令获取可执行文件目标文件名
  • Selenium 页面加载超时pageLoadTimeout与 iframe加载关系解析
  • 对话Michael Truell:23岁创立Cursor,与Github Copilot竞争
  • < 自用文 OS 有关 > (续)发现正在被攻击 后的自救 Fail2ban + IPset + UFW 工作流程详解
  • Elasticsearch面试精讲 Day 7:全文搜索与相关性评分
  • 大数据开发/工程核心目标
  • Redis 客户端与服务器:银行的 “客户服务系统” 全流程
  • 在Ubuntu系统中为MySQL创建root用户和密码
  • 策略模式-不同的鸭子的案例
  • NV169NV200美光固态闪存NV182NV184
  • [Python编程] Python3 字符串
  • Day5-中间件与请求处理
  • C++ 面试高频考点 力扣 153. 寻找旋转排序数组中的最小值 二分查找 题解 每日一题
  • C++ opencv+gstreamer编译,C++ opencv4.5.5+gstreamer1.0 -1.24.12 编译 ,cmake 4.0.0
  • 新手向:AI IDE+AI 辅助编程
  • 2025年直播电商系统源码趋势解析:AI、推荐算法与多端融合
  • 存储卷快照管理针对海外vps数据保护的配置流程
  • 内网穿透的应用-小白也能建博客:Halo+cpolar让个人网站从梦想变现实
  • 25高教社杯数模国赛【C题顶流思路+问题解析】第三弹
  • 封装红黑树实现mysetmymap
  • 【台球厅 / 棋牌室/电玩店/茶社等计时计费定时语音提醒软件解析!】佳易王 计时计费高级版V18.3 实测:双时间显示 + 语音提醒 + 智能记事全解析
  • 【C++】16. set和map
  • mysql安装(压缩包方式8.0及以上)
  • Android约束部分控件顶出范围
  • Firefox Android 开发环境搭建全流程(四)