Set Mismatch leetcode 645

该博客讨论了一种算法问题,即在一个原本包含从1到N的所有整数的无序数组中,由于数据错误导致一个数重复而另一个数丢失。文章提供了两种解法:一种是使用HashMap统计每个元素出现的次数,找出重复和缺失的数;另一种是通过改变数组中元素值的方式来定位重复和缺失的数。这种方法巧妙地利用了数组本身作为数据结构来节省额外的空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.题目描述

The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.

Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.

Example 1:

Input: nums = [1,2,2,4]
Output: [2,3]

Note:

The given array size will in the range [2, 10000].
The given array’s numbers won’t have any order.

用中文来描述这个题:
给一个长度为 N 的数组 nums,数组原本装有 [1…N] 这 N 个元素,并且元素无序。现在出现了一些错误,nums 中的一个元素出现了重复,也就同时导致了另一个元素的缺失。请你写一个算法,找到 nums 中的重复元素和缺失元素的值。

2.解法1

最简单粗暴的解法自然是用个hashmap各元素出现的次数。

    public static void findElement() {
        int[] nums = {1, 2, 2, 4};
        Map<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<nums.length; i++) {
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }

        for(int i=1; i<=nums.length; i++) {
            if (!map.containsKey(i)) {
                System.out.println("missing num is: " + i);
            } else {
                if (map.get(i) == 1) continue;
                else {
                    System.out.println("dup num is: " + i);
                }
            }
        }
    }

该种解法是最直接的计数方法,没啥好说的,只要有java基础的都会。

3.解法2

上面的方法需要开辟一个新的hashmap空间。那么能不能省下这个hashmap的空间呢?

如果遍历每个数字,将其应该出现的位置上的数字变为其相反数。
1.这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数。
2.如果我们再遍历原来的数组,如果发现某个位置上的数字大于0,说明该位置对应的数字没有出现过。

    public static void findElement() {
        int[] nums = {1, 2, 2, 4};
        int dup = -1, missing = -1;
        int n = nums.length;
        for(int i=0; i<n; i++) {
            int index = Math.abs(nums[i]) - 1;
            if (nums[index] < 0) {
                dup = nums[i];
            } else {
                nums[index] *= -1;
            }
        }

        for(int j=0; j<n; j++) {
            if (nums[j] > 0) {
                missing = j + 1;
            }
        }

        System.out.println("dup is: " + dup);
        System.out.println("missing is: " + missing);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值