350. 两个数组的交集 II

题目

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

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

 

进阶

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1的大小比 nums2 小,哪种方法更优?
  • 如果 nums2的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

 

解题方法一

/**
     * 排序 + 双指针
     *
     * 1.首先对两个数组进行排序,然后使用两个指针遍历两个数组。
     * 2.初始时,两个指针分别指向两个数组的头部。
     * 3.每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,
     * 4.如果两个数字相等,将该数字添加到答案,并将两个指针都右移一位。
     * 5.当至少有一个指针超出数组范围时,遍历结束。
     *
     * 时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度。
     * 空间复杂度:O(min(m,n)),其中 m 和 n 分别是两个数组的长度。
     *
     * @param nums1
     * @param nums2
     * @return
     */
    public int[] intersect(int[] nums1, int[] nums2) {
        // 1.数组排序
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        // 2.定义指针、初始化结果数组
        int p1 = 0, p2 = 0, p3 = 0;
        int nums1Len = nums1.length;
        int nums2Len = nums2.length;
        int[] result = new int[Math.min(nums1Len, nums2Len)];
        // 3.遍历数组元素
        // 当至少有一个指针超出数组范围时,遍历结束
        while (p1 < nums1Len && p2 < nums2Len){
            if (nums1[p1] < nums2[p2]) p1++;
            else if (nums2[p2] < nums1[p1]) p2++;
            else {
                result[p3] = nums1[p1];
                p1++;
                p2++;
                p3++;
            }
        }
        // copyOfRange:对一个已有的数组进行截取复制,复制出一个左闭右开区间的数组。
        return Arrays.copyOfRange(result, 0,p3);
    }

 

解题方法二

/**
     * 哈希表
     *
     * 1.首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数
     * 2.然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,
     *   则将该数字添加到答案,并减少哈希表中该数字出现的次数。
     *
     *
     * @param nums1
     * @param nums2
     * @return
     */
    public int[] intersect2(int[] nums1, int[] nums2) {
        // 为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集。
        if (nums1.length > nums2.length) {
            return intersect2(nums2, nums1);
        }
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        // 首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数
        for (int num : nums1) {
            // getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。
            int count = map.getOrDefault(num, 0) + 1;
            map.put(num, count);
        }
        int[] intersection = new int[nums1.length];
        int index = 0;
        // 然后遍历第二个数组
        for (int num : nums2) {
            int count = map.getOrDefault(num, 0);
            // 对于第二个数组中的每个数字,如果在哈希表中存在这个数字
            if (count > 0) {
                // 则将该数字添加到答案
                intersection[index++] = num;
                // 并减少哈希表中该数字出现的次数
                count--;
                // 如果减完大于0,更新count
                if (count > 0) {
                    map.put(num, count);
                } else {
                    // 如果减完小于0,弹出
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }

 

微信关注

WeChat

本站为非盈利性站点,所有资源、文章等仅供学习参考,并不贩卖软件且不存在任何商业目的及用途,如果您访问和下载某文件,表示您同意只将此文件用于参考、学习而非其他用途。
本站所发布的一切软件资源、文章内容、页面内容可能整理来自于互联网,在此郑重声明本站仅限用于学习和研究目的;并告知用户不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
如果本站相关内容有侵犯到您的合法权益,请仔细阅读本站公布的投诉指引页相关内容联系我,依法依规进行处理!
作者:理想
链接:https://www.imyjs.cn/archives/592
THE END
二维码
350. 两个数组的交集 II
题目 给你两个整数数组 nums1 和 nums2 ,请你以数……
<<上一篇
下一篇>>
文章目录
关闭
目 录