算法详解:寻找缺失的第一个正数
2023-10-09 21:58:26
算法概述
给定一个未排序的整数数组,寻找其中没有出现的最小的正整数。例如,对于数组 [1, 2, 0, -5, 3]
, 缺失的第一个正整数是 4
,而对于数组 [0, 1, 2, 3]
, 则为 4
。
要解决这个问题,我们提出了一种有效且高效的算法。该算法遵循以下步骤:
- 首先,我们将数组中的所有正整数移动到数组的前部。
- 然后,对数组中正整数的位置进行调整,使其满足每个数字的索引等于该数字减一。
- 最后,遍历数组,找到第一个缺失的正整数,即第一个未被占用的索引加一。
算法实现
1. 将正整数移动到数组的前部
我们将使用一个双指针法来实现这一步。我们将两个指针都初始化为 0。左指针指向数组的起始位置,而右指针指向数组的末尾。然后,我们循环检查右指针指向的元素。如果该元素为正整数,我们将该元素与左指针指向的元素交换,并同时将左指针和右指针都右移一位。如果该元素为负整数或零,则我们仅右移右指针。
2. 调整正整数的位置
在第一步中,我们将所有正整数都移动到了数组的前部。现在,我们需要将这些正整数的位置调整正确。我们可以通过以下步骤来实现:
- 我们遍历数组中正整数的位置。
- 对于每个正整数,我们计算其正确位置的索引。该索引等于该正整数减一。
- 如果该正整数不在其正确位置,我们将该正整数与该位置处的元素交换。
3. 查找缺失的第一个正整数
在第二步中,我们将所有正整数都调整到了正确的位置。现在,我们需要找到第一个缺失的正整数。我们可以通过以下步骤来实现:
- 我们遍历数组中正整数的位置。
- 对于每个正整数,我们检查该正整数的索引是否等于该正整数减一。
- 如果该正整数的索引不等于该正整数减一,则说明该正整数的索引加一就是第一个缺失的正整数。
算法分析
时间复杂度
该算法的时间复杂度为 O(n),其中 n 是数组的长度。我们在步骤 1 和步骤 2 中都使用了双指针法,该方法的平均时间复杂度为 O(n)。步骤 3 中的遍历操作也需要 O(n) 的时间。
空间复杂度
该算法只需要常数级别的额外空间。我们在步骤 1 和步骤 2 中使用了两个指针,这需要两个额外的变量。在步骤 3 中,我们也需要一个额外的变量来存储第一个缺失的正整数。因此,该算法的空间复杂度为 O(1)。
边界情况
如果数组中没有正整数,则第一个缺失的正整数为 1。如果数组中没有负整数或零,则该算法将始终返回 1。
示例
对于数组 [1, 2, 0, -5, 3]
, 该算法将返回 4。
对于数组 [0, 1, 2, 3]
, 该算法将返回 4。
对于数组 [-1, -2, -3]
, 该算法将返回 1。
对于数组 []
, 该算法将返回 1。
结论
本文详细解析了算法题“查找缺失的第一个正数”,提供了一种时间复杂度为 O(n) 且仅使用常数级别额外空间的解决方案。我们还讨论了该算法的实现细节和一些边界情况的处理。希望本文对有志于算法学习的读者有所帮助。