First Missing Positive
Question
Given an unsorted integer array, find the first missing positive integer.
Example
Given [1,2,0]
return 3
, and [3,4,-1,1]
return 2
.
Challenge
Your algorithm should run in O(n)
time and uses constant space.
Thoughts
not O(n)
如果不要求O(n)
的话,我们可以先sort然后再找
O(n)
常见的能达到线性时间复杂度的排序算法有 基数排序,计数排序 和 桶排序。
基数排序显然不太适合这道题,计数排序对元素落在一定区间且重复值较多的情况十分有效,且需要额外的 O(n)O(n) 空间,对这道题不太合适。最后就只剩下桶排序了,桶排序通常需要按照一定规则将值放入桶中,一般需要额外的 O(n)O(n) 空间,咋看一下似乎不太适合在这道题中使用,但是若能设定一定的规则原地交换原数组的值呢?这道题的难点就在于这种规则的设定。
设想我们对给定数组使用桶排序的思想排序,第一个桶放1,第二个桶放2,如果找不到相应的数,则相应的桶的值不变(可能为负值,也可能为其他值)。
那么怎么才能做到原地排序呢?即若 A[i] = xA[i]=x, 则将 x 放到它该去的地方 - A[x - 1] = xA[x−1]=x, 同时将原来 A[x - 1]A[x−1] 地方的值交换给 A[i]A[i].
排好序后遍历桶,如果不满足 f[i] = i + 1f[i]=i+1, 那么警察叔叔就是它了!如果都满足条件怎么办?那就返回给定数组大小再加1呗。
Solution
class Solution:
# @param A, a list of integers
# @return an integer
def firstMissingPositive(self, A):
# write your code here
if not A:
return 1
length = len(A)
index = 0
while index < length:
if A[index] <= 0:
index += 1
else:
if A[index] <= length:
if A[index] == A[A[index] - 1] or A[index] == index + 1:
#take care of the situation that should move on
index += 1
continue
tmp = A[A[index]-1]
A[A[index]-1] = A[index]
A[index] = tmp
#doesn't increase the index here
else:
index += 1
for i in range(length):
if A[i] != i+1:
return i+1
#if not return yet, the missing positive number would be length + 1
return length + 1