常见算法题解

-.查找缺失和重复的元素

给一个长度为 N 的数组 nums,其中本来装着 [1..N] 这 N 个元素,无序。但是现在出现了一些错误,nums 中的一个元素出现了重复,也就同时导致了另一个元素的缺失。请你写一个算法,找到 nums 中的重复元素和缺失元素的值。

 分析: 重复的数字在数组中出现 2 次,丢失的数字在数组中出现 0 次,其余的每个数字在数组中出现 1 次。因此可以使用哈希表记录每个元素在数组中出现的次数,然后遍历从 1 到 n 的每个数字,分别找到出现 2 次和出现 0 次的数字,即为重复的数字和丢失的数字。

1.使用哈希表

public class FindDumAndMis {

    public int[] find(int[] array) {

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        int[] errorNums = new int[2];

        for (int num: array) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        for (int i = 0; i < array.length; i++) {
            Integer count = map.getOrDefault(i, 0);
            if (count == 2) {
                errorNums[0] = i;
            }else if (count == 0) {
                errorNums[1] = i;
            }
        }
        return errorNums;
    }
}

2.排序

将 nums 中的元素变为 [0..N-1],这样每个元素就和一个数组索引完全对应了, 通过将每个索引对应的元素变成负数,以表示这个索引被对应过一次了:

这样会导致有两个元素对应到了同一个索引(重复),而且会有一个索引没有元素对应过去(缺失)。

class Solution {
    public int[] findErrorNums(int[] nums) {
        int n = nums.length;
        int dup = -1;
        for (int i = 0; i < n; i++) {
        // 元素是从 1 开始的
            int index = Math.abs(nums[i]) - 1;
            // nums[index] 小于 0 则说明重复访问
            if (nums[index] < 0)
                dup = Math.abs(nums[i]);
            else
                nums[index] *= -1;
        }
        int missing = -1;
        for (int i = 0; i < n; i++)
            // nums[i] 大于 0 则说明没有访问
            if (nums[i] > 0)
        // 将索引转换成元素
                missing = i + 1;
        return new int[]{dup, missing};
    }
}
原文地址:https://www.cnblogs.com/jiefangzhe/p/15075083.html