LeetCode-Find All Numbers Disappeared in an Array

Description:
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]

题意:给定一个一维数组,里面的数字可能重复出现两次,出现的数字在[1,n]这个区间内,要求找出数组中不在区间内的数字,并且时间复杂度为O(n),以及除了返回的list外无额外的存储开销;

解法一(超时):最简单的解法就是将[1,n]的数字存储在list中,之后遍历一遍数组,将数组中出现的数字从list中删除,那么剩下的就是没有出现的数字了,但是对list的删除操作会花费很多的时间,结果导致了超时;

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> result = new LinkedList<>();
        for(int i=0; i<nums.length;i++) {
            result.add(i+1);
        }
        for(int x : nums) {
            if (result.contains(x)) {
                result.remove((Object)x);
            }
        }
        return result;
    }
}

解法二:既然给定的数组中的数字在[1,n]的范围内,那么我们可以让出现过的数字在对应数组下标处标记,可以将其值表示为负数,那么遍历过一遍后,数组中为正数的那个下标处的数字就是没有出现过的;
举例说明,对于数组nums=[4,3,2,2]来说,我们遍历这个数组
当i=0时,令nums[nums[i] - 1] = nums[4 - 1] = 2为负数,表示此时数字4出现过;——nums = [4,3,2,-2]
当i=1时,令nums[nums[i] - 1] = nums[3 - 1] = 2为负数,
表示此时数字3出现过;——nums = [4,3,-2,-2]
当i=2时,令nums[nums[i] - 1] = nums[2 - 1] = 3为负数,
表示此时数字2出现过;——nums = [4,-3,-2,-2]
当i=3时,由于此时nums[nums[i] - 1] = nums[2 - 1]已经为负数了,所以不用改变;——nums = [4,-3,-2,-2]
从最后的数组中,我们可以看到,只有一个正数,出现在下标0除,即区间[1,4]内没有出现的数字为(0+1)=1;

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> result = new LinkedList<>();
        for(int i = 0; i < nums.length; i++) {
            int value = Math.abs(nums[i]) - 1;
            if (nums[value] > 0) {
                nums[value] *= -1;
            }
        }
        for(int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                result.add(i + 1);
            }
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值