缺失的第一个正数。给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
示例 1:
1 |
|
示例 2:
1 |
|
示例 3:
1 |
|
说明:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
思路一
交换法。假设数组中第 i
个位置正好存放正数 i+1
,那么遍历一边数组,当第 i
个位置上不是 i+1
的时候,即缺少最小正数 i+1
。所以先通过一遍循环,将符合要求的正数 k
放入第 k-1
个位置,不满足要求的数比如非正数或者大于数组长度的数可以直接跳过,然后在遍历一遍数组即可找到缺失的最小的正数。
值得注意的是,当数组中出现重复元素,比如 [1, 1]
时,要单独考虑。
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
1 |
|
思路二
标记法,假设我们现在可以有额外的空间,对于一个数组,例如 nums = [3,4,-1,-1,8]
,我们创建一个等大的数组,初始化为 [False, False, False, False, False]
,如果 nums
中有 1
,就把第一个位置 a[0] = True
,如果 nums
中有 m
,就令 a[m-1] = True
。最后遍历一遍数组,遇到不为 True
的下标 k
时,缺少的最小正数即为 k + 1
。
然而此时我们没有额外的空间,这时,我们可以把原数组 nums
就当做标记数组,开始时数组中的值为 False
,因此我们把正数当做 False
,负数当做 True
,这时当我们需要标记一个正数存在时,只需要取相反数即可,这样做在遍历数字的时候只需要取绝对值,就得到原来的数了。
但是上述方法带来的问题是,去绝对值得话,之前存在的负数会造成干扰,因此,我们需要把正数和负数分开,即将正数放在前面,将负数放在后面。
1 |
|