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

[Java恶补day17] 41. 缺失的第一个正数

给你一个未排序的整数数组 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 <= 10 5 10^5 105
$-2^{31} <= nums[i] <= 2 31 − 1 2^{31} - 1 2311


知识点:
数组、哈希表


解:
核心思路:让每个元素移动到正确的位置上。令位置编号∈ [ 1 , 2 , . . . , n ] [1, 2, ..., n] [1,2,...,n],并有:正整数元素值∈ [ 1 , 2 , . . . , n ] [1, 2, ..., n] [1,2,...,n],位置下标∈ [ 0 , 1 , . . . , n − 1 ] [0, 1, ..., n-1] [0,1,...,n1],最终让数值=i的数,映射到下标=i-1的位置

按以下步骤进行:
遍历每个元素,将元素移动到正确位置
对于每个遍历的元素,进行while循环判断:若当前遍历的元素值∈[1, n],但不在正确的位置,就需要交换当前元素nums[i]、当前元素值代表的位置上的那个元素nums[nums[i]-1](后者里面包含-1是因为数组下标从0开始)。
在while循环的判断条件中,nums[i] != nums[nums[i] - 1]是为了避免数组存在重复元素却重复交换而导致死循环的情况
找到第一个位置编号与元素值不匹配的元素
因为编号=下标+1,所以是nums[i]i + 1进行判断。
若所有元素都在正确位置,则第一个不匹配的元素是最后一个元素的下一个
这里就是return语句,返回n+1

以测试用例[2, 3, 1, 2]为例:
①数组下标若从1开始:
测试用例[2, 3, 1, 2]
②实际数组下标从0开始:
测试用例[2, 3, 1, 2]

时间复杂度: O ( n ) O(n) O(n)。2个并列的for循环,每个for循环只遍历一次整个数组。
空间复杂度: O ( 1 ) O(1) O(1)。没有用额外的辅助数组。

class Solution {public int firstMissingPositive(int[] nums) {//不关心:非正数、重复元素//获取数组长度int n = nums.length;//遍历每个元素,将元素移动到正确位置for (int i = 0; i < n; i++) {//若当前遍历的元素值∈[1, n],但不在对应位置,则交换元素到正确位置while (nums[i] >= 1 && nums[i] <= n && nums[i] != nums[nums[i] - 1]) {//同个位置会重复检测直至在正确位置,才会进入下一个位置的检测int j = nums[i] - 1;int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}}//找到第一个位置编号与元素值不匹配的元素for (int i = 0; i < n; i++) {//返回第一个不匹配位置的编号(编号=下标+1)if (nums[i] != i + 1) {return i + 1;}}//若所有元素都在正确位置,则第一个不匹配的元素是最后一个元素的下一个return n + 1;}
}

参考:
1、灵神解析

http://www.xdnf.cn/news/905815.html

相关文章:

  • AirSim/Cosys-AirSim 游戏开发(三)打包可执行文件
  • spring获取注册的bean并注册到自定义工厂中管理
  • 【大模型】大模型数据训练格式
  • 光纤采集系统
  • grafana-mcp-analyzer:基于 MCP 的轻量 AI 分析监控图表的运维神器!
  • 【计算机网络】HTTP
  • 安徽省N1 叉车司机考试题及答案解析
  • webui无法注册如何配置
  • volka 25个短语动词
  • Android动态广播注册收发原理
  • (4-point Likert scale)4 点李克特量表是什么
  • 基于cornerstone3D的dicom影像浏览器 第二十九章 自定义菜单组件
  • openvino使用教程
  • LangChain【7】之工具创建和错误处理策略
  • Linux 内核性能分析确保成效的关键知识点总结
  • Redis 过期了解
  • ​​TLV4062-Q1​​、TLV4082-Q1​​迟滞电压比较器应用笔记
  • MySQL 高级学习篇
  • 【SpringBoot自动化部署】
  • 【WebSocket】SpringBoot项目中使用WebSocket
  • 主流定位技术:Zigbee、蓝牙、UWB、RFID、5G通信介绍及对比
  • Day 41 训练
  • 鸿蒙图片缓存(一)
  • 2025年7月-12月【CISP】考试计划时间
  • 全新Xsens Animate版本是迄今为止最大的软件升级,提供更清晰的数据、快捷的工作流程以及从录制开始就更直观的体验
  • C++11 Move Constructors and Move Assignment Operators 从入门到精通
  • 现代Web安全实践:基于Token与Refresh Token的单点登录(SSO)实现
  • Java常用的判空方法
  • 数据库学习(一)——MySQL基础
  • 信息化安全与自主可控需求:国产飞腾D2000 VPX3U主板设计与实践