LeetCode-350-IntersectionOfTwoArraysII


LeetCode-350-IntersectionOfTwoArraysII

350两个数组的交集II

题目描述

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

这个题和349几乎相同,区别是349中加了去重的判断

示例

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]


说明:

输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

题解一:

    /**
     * 思路:
     *      1.初始化nums1为map{value, counter(出现次数)}字典形式
     *      2.遍历nums2如果包含当前value并且counter大于0则符合查找条件
     *
     * 时间复杂度:O(n)
     * 空间复杂度:O(n)
     *
     * @param nums1 数组1
     * @param nums2 数组2
     * @return 交集数组
     */
    public int[] intersect1(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null) {
            return new int[]{};
        }
        Map dic = new HashMap<>(nums1.length);
        for (int num : nums1) {
            Integer counter = dic.getOrDefault(num, 0);
            dic.put(num, counter + 1);
        }
        int[] arr = new int[Math.min(nums1.length, nums2.length)];
        int index = 0;
        for (int num : nums2) {
            if (dic.containsKey(num)) {
                Integer counter = dic.get(num);
                if (counter > 0) {
                    arr[index++] = num;
                    dic.put(num, counter -1);
                }
            }
        }
        return Arrays.copyOfRange(arr, 0, index);
    }

题解二:

与349的题解三的唯一区别是去掉了if的去重判断

    /**
     * 思路:
     *      1.使用快排分别把两个数组从小到大(从大到小)排列
     *      2.遍历两数组进行比较
     *
     * 时间复杂度:O(n*logn)
     * 空间复杂度:O(logn)
     *
     * @param nums1 数组1
     * @param nums2 数组2
     * @return 交集数组
     */
    public int[] intersection2(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null) {
            return new int[]{};
        }
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int index1 = 0;
        int index2 = 0;
        // 这里集合需要比较上一个的值就直接初始化一个数组
        int index = 0;
        // 取最小是为了节约空间,多申请一个空间的目的是使用index=0的位置减少if判断
        int[] arr = new int[(Math.min(nums1.length, nums2.length)) + 1];

        while (index1 < nums1.length && index2 < nums2.length) {
            if (nums1[index1] == nums2[index2]) {
                // 相对于349题这里我们不再需要去重,直接把if判断去掉即可
                arr[++index] = nums1[index1];
                index1++;
                index2++;
            } else if (nums1[index1] > nums2[index2]) {
                index2++;
            } else {
                index1++;
            }
        }
        return Arrays.copyOfRange(arr, 1, index + 1);
    }

题解三:

与题解二的区别是不在需要多申请1个空间来舍去去重判断

    /**
     * 思路:
     *      1.使用快排分别把两个数组从小到大(从大到小)排列
     *      2.遍历两数组进行比较
     *
     * 时间复杂度:O(n*logn)
     * 空间复杂度:O(logn)
     *
     * @param nums1 数组1
     * @param nums2 数组2
     * @return 交集数组
     */
    public int[] intersect3(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null) {
            return new int[]{};
        }
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int index1 = 0;
        int index2 = 0;
        // 这里集合需要比较上一个的值就直接初始化一个数组
        int index = 0;
        // 取最小是为了节约空间,这里不再需要去重,index指向尾部元素的下一个位置下标,不用多申请一个空间
        int[] arr = new int[Math.min(nums1.length, nums2.length)];

        while (index1 < nums1.length && index2 < nums2.length) {
            if (nums1[index1] == nums2[index2]) {
                // 这里的index指向的数组中的尾部元素的下一个位置下标
                arr[index++] = nums1[index1];
                index1++;
                index2++;
            } else if (nums1[index1] > nums2[index2]) {
                index2++;
            } else {
                index1++;
            }
        }
        return Arrays.copyOfRange(arr, 0, index);
    }

文章作者: Tariq
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Tariq !
  目录