• [LeetCode] 448. Find All Numbers Disappeared in an Array


    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)的复杂度内解决
    那么我们就只能对原数组做操作了。
    其一,我们改变数组元素的值,因为数字是1-n的,我们可以顺着下标去访问(正好是那个位置应该出现的),把那个位置的元素改变成负数
    为什么改变成负数,因为这个位置我们可能还没访问到,这个数据我们是需要的,所以我们改成负数,当一轮搜完之后
    不是负数的位置,就是我们要添加的。
    注意:下标是0到n-1的,数字是1-n的
    class Solution {
        public List<Integer> findDisappearedNumbers(int[] nums) {
            List<Integer> list = new ArrayList<>();
            if (nums.length == 0)
                return list;
            for (int i = 0; i < nums.length; i++) {
                int j = Math.abs(nums[i]) - 1;
                nums[j] = nums[j] > 0 ? -nums[j] : nums[j];
            }
            for (int i = 0; i < nums.length; i++)
                if (nums[i] > 0)
                    list.add(i + 1);
            return list;
        }
    }
    其二,我们可以对数组排序,相信大家都能想到,如果对数组排序了,缺失的就一目了然了,然而不开空间下,最快的排序也得O(nlogn)
    而桶排和计数排序都是要额外开空间的,那么我们就需要在O(n)的情况下对其排序,要做到这点,我们就需要再去看条件
    它是1到n的可以与下标1到n-1对应,也就是说,如果每个数字只出现一次的情况下,应该是
    下标 0 1 2 ... n-1
    数字 1 2 3 ... n
    那么我们可以直接把每个数字都放到它相应的位置上,注意这里有重复的数字,就把他们放在不存在数的位置上(也就是说这个时候,下标不等于数字-1)
    最后我们遍历一遍找出不同的即可
    class Solution {
        private void swap(int[] nums, int i, int j) {
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
        public List<Integer> findDisappearedNumbers(int[] nums) {
            List<Integer> list = new ArrayList<>();
            if (nums.length == 0)
                return list;
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] != nums[nums[i] - 1]) {
                    swap(nums, nums[i] - 1, i);
                    i--;
                }
            }
            for (int i = 0; i < nums.length; i++)
                if ((nums[i] - 1) != i)
                    list.add(i + 1);
            return list;
    
        }
    }
    
    
    
     
  • 相关阅读:
    典型分布式系统分析:MapReduce
    linux下如何查看自己都装了什么服务
    docker
    linux的命令操作
    IDEA去除掉虚线,波浪线,和下划线实线的方法
    在linux下安装配置rabbitMQ详细教程
    在linux下安装配置rabbitMQ详细教程
    Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
    shell之startup
    shell脚本特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)
  • 原文地址:https://www.cnblogs.com/Moriarty-cx/p/9784333.html
Copyright © 2020-2023  润新知