41. 第一个缺失的正数

题目:

给一个未排序的数组,找出第一个缺失的正整数。

例如,
[1,2,0] 返回 3
[3,4,-1,1] 返回 2

你的算法应该在 O(n) 的时间复杂度内完成并且使用常数量的空间。

分析:

  1. 寻找缺失正整数,因此所有1以下数字均无效
  2. 定义字典用于标记对应数值存在
  3. 遍历列表,将出现的有效数字加入字典,如果1在列表中,改变相应flag
  4. 从1开始递增,在字典中查询是否存在,不存在即为缺失正整数

代码:

class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if not n :
            return 1
        minposNum = 2
        numDict = {}
        for x in nums:
            if x > 0:
                numDict[x] = 1
                if x == 1:
                    minposNum = 1
        if minposNum > 1:
            return 1
        else:
            i = 1
            while n:
                if not numDict.get(i):
                    return i
                n -= 1
                i += 1
        return i

思考:

  1. 以上代码时间复杂度O(n),空间复杂度O(n),未能实现要求的O(1)空间复杂度
  2. 从讨论区内学习到了满足时间空间复杂度要求的方法
  3. 思路为,去除小于1及大于n的无效数据,以hash键值方式,将x[i]%n值加n,这样做的方式不会导致当前元素后部元素改写导致的hash键值改变,重写后,1~n中缺失的整数对应位置将为小于n的整数,再次遍历,寻找第一次出现的小于n的位置;
  4. 代码如下:(leetcode asones
     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




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yzpwslc

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值