41. First Missing Positive

题意: 给定一个未排序的整数数组,找到第一个丢失的正整数。

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.

思路:开始的时候,题意理解错了,以为是找出一段数字中丢失的数,那个难做啊。。。后来仔细看了一遍题目才理解了。其实这题并不算难,但是有很多细节是需要考虑的,就是把每个数放到它对应的索引上,比如2,3,1,4就转为成1,2,3,4,这样很简单就能把丢失的数找出来了。

方法一:

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

这里最好使用while,我已开始用for,比如:[0,3,2,4]这个数组,4和3换位置之后,4就再也不动了。。。所以思考还是要仔细,最后for这里一定要返回索引+1,而不是数,这样对于[],[0]这样的数组就能处理了。

方法二:

 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

这是discussion里的一段代码,链接在此 戳我,这个方法非常巧妙,作者开始先把大于等于n和小于0的数都去除了(n是append(0)只有的数组长度,append(0)是为了处理空数组的情况),那么剩余的数就是小于n,之后对于任何出现的数都把它加n,使它大于等于n,那么剩下num[i]小于n对应的i就是没出现的数了,这里要注意的是其实+n相当于置标志位,但是又防止了相同值得出现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值