【题目】
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
示例 1:
输入: nums = [1,2,0]
输出: 3
示例 2:
输入: nums = [3,4,-1,1]
输出: 2
示例 3:
输入: nums = [7,8,9,11,12]
输出: 1
提示:
1 <= nums.length <= 5 * 10^5-2^31 <= nums[i] <= 2^31 - 1
【题目解析】
思路
本题的解决方法是基于集合的差集操作。首先,生成一个包含从1到len(nums) + 1的整数的集合,这个范围覆盖了可能的最小缺失正数。然后,将输入数组转换为另一个集合,以便快速访问。最后,使用集合的差集操作来找出第一个不存在于数组中的最小正数。
算法描述
- 生成一个预期的正数集合,范围从
1到len(nums) + 1。 - 将输入数组
nums转换为集合。 - 计算两个集合的差集,得到缺失的正数集合。
- 返回差集中的最小元素。
class Solution:
def firstMissingPositive(self, nums):
# 创建一个从1开始到len(nums)+1的整数集合
# 这是因为最坏情况下,缺失的第一个正数可能是比数组长度还要大的数
expected_nums_set = set(range(1, len(nums) + 2))
# 将输入的nums数组转换为集合,这样就能快速检查一个数是否存在于nums中
nums_set = set(nums)
# 计算两个集合的差集,这将返回在expected_nums_set中但不在nums_set中的所有元素
# 差集就代表了数组nums中缺失的正整数
# 找到这个差集中的最小元素,这就是缺失的最小正数
return min(expected_nums_set - nums_set)
执行
【总结】
适用问题类型
这种方法适用于需要从一系列数字中找出缺失或未出现的元素的问题。尤其是当问题的数据范围有限,且对于时间效率的要求高于空间效率时,这种方法尤为有效。典型应用场景包括数字序列的完整性校验、数据完整性分析以及寻找未出现的最小元素等。
解决算法
这道题使用的是集合差集算法,该算法基于集合理论中的差集概念,通过构建一个完整的正数集合,然后从中剔除输入数组中已存在的元素,最终获得缺失元素的集合。
算法特点
- 时间效率:由于集合在Python中的实现是基于哈希表,因此差集操作的时间复杂度非常低。
- 空间使用:这种方法的空间复杂度为O(n),因为需要构建一个与输入数组长度相当的集合。
- 代码简洁:使用集合差集可以大幅简化代码逻辑,避免了复杂的循环和条件判断。
算法优化与实践意义
尽管本算法不满足原问题对常数空间复杂度的要求,但它在实践中的表现可能足够优秀,尤其是在处理较小数据集时。为了进一步优化这种方法,可以考虑以下方向:
- 优化空间使用:在保持时间复杂度不变的前提下,尝试减少所需的额外空间,如原地修改数组来跟踪元素的存在性。
- 算法适配:对于大数据集,可以探索更节省空间的算法,如位图方法。
- 实践应用:在实际应用中,如在内存使用不是主要瓶颈的场合,此算法可以作为快速原型和解决方案的实现。
在实际工程实践中,算法的选择需要根据具体的应用场景、资源限制和性能要求来权衡。对于不同的问题,应当灵活选择最合适的算法策略。