1. 题目解析与核心思路
这道题目要求我们在一个未排序的整数数组中找到缺失的最小正整数。乍一看似乎很简单,但题目要求时间复杂度为O(n)且只能使用常数级别的额外空间,这就让问题变得非常具有挑战性。
首先明确几个关键点:
- 我们需要找的是"第一个缺失的正整数",也就是说从1开始检查,第一个不在数组中的正整数就是答案
- 数组可能包含负数、零和重复的数字
- 数组长度为n时,答案的可能范围是1到n+1(如果1到n都出现了,那么答案就是n+1)
1.1 暴力解法分析
最直观的解法是:
- 从1开始逐个检查是否在数组中
- 第一个不在数组中的正整数就是答案
但这种解法时间复杂度是O(n²),因为对于每个数字都要遍历整个数组检查是否存在。显然不符合题目要求。
1.2 哈希表优化思路
我们可以用哈希表来优化查找过程:
- 将所有数字存入哈希表
- 从1开始检查哈希表中是否存在
- 第一个不在哈希表中的正整数就是答案
这样时间复杂度降为O(n),但需要O(n)的额外空间存储哈希表,仍然不符合空间复杂度要求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 原地哈希算法详解
为了同时满足时间和空间复杂度要求,我们需要使用"原地哈希"的技巧。核心思想是利用数组本身作为哈希表,通过交换元素的位置来标记数字是否存在。
2.1 算法步骤
- 首先处理所有非正数:将它们设置为n+1(因为答案最大就是n+1)
- 遍历数组,对于每个数字的绝对值x:
- 如果x在1到n范围内,将数组中第x-1位置的数字变为负数(标记x存在)
- 最后遍历数组,第一个正数所在的位置i+1就是缺失的最小正整数
- 如果都是负数,说明1到n都存在,返回n+1
2.2 具体实现
python复制def firstMissingPositive(nums):
n = len(nums)
# 第一步:将所有非正数标记为n+1
for i in range(n):
if nums[i] <= 0:
nums[i] = n + 1
# 第二步:使用负号标记存在的数字
for i in range(n):
num = abs(nums[i])
