找到所有数组中消失的数字-python

leetCode第448题 找到所有数组中消失的数字

给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

示例 1:

输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]

示例 2:

输入:nums = [1,1]
输出:[2]

提示:

n == nums.length
1 <= n <= 105
1 <= nums[i] <= n

进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。

在python中判断一个元素在列表中直接用 元素名 in 列表名就能判断

   dis = []
      for i in range(1,len(nums)+1):
          if i not in nums:
              dis.append(i)

但这种写法每次判断一个元素就要遍历整个列表,势必会导致超时
而且与题中进阶的要求也不符合,就算记录成hash map然后检索,也是占用了而外的空间

要想时间复杂度为O(n),且不占用而外的空间,那么我们只能利用数组本身,这很难让人找到灵感。
以[4,3,2,7,8,2,3,1]为例,我们要把数字和下标联系起来,但是不能使用hash map。
-------------------------------
要在一遍循环内找到消失的数,就得利用题中给的条件:所有的数都在1-n之间,我们需要做一个变换,使得他的值不在1-n,这样通过一个范围的比较就能发现哪些数不对。
-----------------------------
数组本身只能告诉我们两个信息,一个是下标,另一个是数值,这势必要将数值和下标联系起来。在python中,下标是从0开始,我们将第一个数字4为例,将4-1得到下标3,我们将列表的3对应的值做一个变换,使得它不在1-n,不妨直接添一个负号(也可以直接加上n,使范围不在1-n),得到的是-7,对第二个元素3,使下标2应的值变为负数,得到-2,如果已经是负数,就不必更改。
------------------------------
这样[4,3,2,7,8,2,3,1],就变成了[-4,-3,-2,-7,8,2,-3,1],这样我们可以看到下标4,5对应的值还是整数。因为python的下标从0开始,所以对应的是缺失了5和6。
-------------------------------
因为数据中缺失了5,6所以我们无法操作下标4,5,反过来,下标对应的值没被更改,就是因为缺失了操作下标的数。

## python3
class Solution:
    def findDisappearedNumbers(self, nums: [int]) -> [int]:
        for i in range(len(nums)):
            index = abs(nums[i])-1
            if nums[index] > 0:
                nums[index] = -nums[index]
        dis = []
        for i in range(len(nums)):
            if nums[i] > 0:
                dis.append(i+1)
        return dis

也可以用+n的操作,使数值不在1-n这个范围,进一步判断

## python3
class Solution:
    def findDisappearedNumbers(self, nums: [int]) -> [int]:
        n = len(nums)
        for i in range(n):
            index = (nums[i]-1)%n
            nums[index] += n
        dis = []
        for i in range(n):
            if(nums[i] <= n):
                dis.append(i+1)
        return dis
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

unseven

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

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

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

打赏作者

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

抵扣说明:

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

余额充值