[Lintcode]189. First Missing Positive

189. First Missing Positive

Description

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.

别人的代码1

def firstMissingPositive(self, nums):
    """
    :type nums: List[int]
    :rtype: int
     Basic idea:
    1. for any array whose length is l, the first missing positive must be in range [1,...,l+1], 
        so we only have to care about those elements in this range and remove the rest.
    2. we can use the array index as the hash to restore the frequency of each number within 
         the range [1,...,l+1] 
    """
    nums.append(0)
    n = len(nums)
    for i in range(len(nums)): #delete those useless elements
        if nums[i]<0 or nums[i]>=n:
            nums[i]=0
    for i in range(len(nums)): #use the index as the hash to record the frequency of each number
        nums[nums[i]%n]+=n
    for i in range(1,len(nums)):
        if nums[i]/n==0:
            return i
    return n

思路:

  • 时间复杂度: O(n)
  • 空间复杂度:O(1)

这道题没想出来。
最后看了Leetcode的Discussion部分。
这个做法真的相当巧妙。
有点类似于十位用来计数,个位用来记录数字。

  1. 首先的小tricks我是想到了。如果数组个数为len的话,那缺失的整数肯定在1到len+1之间,所以大于len+1的整数,肯定不是最小的missing positive。其中又可分为两种情况,一是在1~len,即中间存在缺失,或者是连续整数的list,那第一个missing positive则为len+1。

  2. 之后的操作非常值得借鉴。
    因为要求extra space为有限。所以他用原来的list做为就记录空间。为了避免计数功能和记录功能冲突,他选择用数组中第i位作为i的记录区,而用“+n”计数。因为记录的数字经过(1)的操作,均在[1,len]之间,所以只需要用到余数部分,不会和计数部分有冲突。

  3. 最后要注意一个小点就是,一开始append(0),这是为了防止出现最大值是len+1的情况。

由于最后考察的用例实际不长,所以其实也可以直接用简单的:

		i = 1
        while i in A:
            i += 1
        return i

别人的代码2

class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        i=0
        while i<len(nums):
            if nums[i]-1<len(nums) and nums[i]>0 and nums[nums[i]-1]!=nums[i]:
                nums[nums[i]-1],nums[i]=nums[i],nums[nums[i]-1]
            else:
                i+=1
        for i,num in enumerate(nums):
            if num!=i+1:
                return i+1
        return len(nums)+1

思路

这里同样是利用同一个数组做记录。

posted @ 2019-01-08 15:23  siriusli  阅读(161)  评论(0编辑  收藏  举报