【leetcode】找到所有数组中消失的数字

class Solution:
    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
        # Solution 1:
        """
        # 总共2次遍历,由于题目限制不适用额外的空间,也就是不能用哈希表,那么只能在数组上原地操作
        # 利用提示:n == nums.length
        # 第1次遍历:把nums[i]!=(i+1)的元素放到nums[i]!=(i+1)的下标位置上
        for i in range(0, len(nums)):
            if nums[i] != (i+1):
                x = nums[i]
                while x != nums[x-1]:
                    # 放到nums[j] == (j+1)的下标位置
                    tmp = nums[x-1]
                    nums[x-1] = x 
                    x = tmp
        # 第2次遍历:nums[i]!=(i+1)的(i+1)就是缺失的数字
        res = []
        for i in range(0, len(nums)):
            if nums[i] != (i+1):
                res.append(i+1)
        return res
        """

        # Solution 2
        # 将原始数组当作哈希表,给元素执行某种变换之后还能够还原元素的真实值
        # 可以做取负数变换,也可以加上n的变换,通过取模获得原始元素
        # 取负数变换速度慢,因为要判断是否是负数,加上n变换速度快一些,因为不需要额外的判断了
        """
        for i in range(0, len(nums)):
            # 还原元素真实的值
            if nums[i] < 0 :
                x = -nums[i]
            else:
                x = nums[i]
            # 给x-1下标做标记,说明x元素出现过
            # 这里仍然需要判断nums[x-1]是否为负数
            # 如果nums[x-1]是负数,说明已经标记过,x出现过多次,这种情形不做任何操作
            if nums[x-1] > 0:
                nums[x-1] = -nums[x-1]
        # 第2次遍历:没有变成负数的元素,对应下标i+1是没有出现过的元素
        res = [i+1 for i in range(0, len(nums)) if nums[i]>0]
        return res
        """

        # Solution 3
        n = len(nums)
        # 第1次遍历:做加上n的变换
        for num in nums:
            # 取出来的数是真实元素-1
            x = (num-1) % n
            nums[x] += n
        # 第2次遍历:仍然小于n的元素对应的下标i+1是没有出现过的元素
        res = [i+1 for i, num in enumerate(nums) if num<=n]
        return res

猜你喜欢

转载自blog.csdn.net/ningmengzhihe/article/details/127821705