Skip to content

350.两个数组的交集Ⅱ

难度:简单

给你两个整数数组 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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

解题思路

类似 76 题,把 num1 中的数字和对应数量存进哈希表 integerMap,再按顺序遍历 nums2 数组,同时逐个与 integers 集合进行比对,若 integers 中存在对应的内容,则将其存储进 result 数组,最后返回 result 即可。

我的代码(哈希表)

java
public int[] intersect(int[] nums1, int[] nums2) {
    // 使用HashMap来记录nums1中元素出现的次数
    HashMap<Integer, Integer> integerMap = new HashMap<>();
    // 创建一个ArrayList来存储交集结果
    ArrayList<Integer> resultList = new ArrayList<>();
    for (int i = 0; i < nums1.length; i++) {
        integerMap.put(nums1[i], integerMap.getOrDefault(nums1[i], 0) + 1);
    }
    // 检查元素在nums1中是否存在且计数大于0
    for (int i = 0; i < nums2.length; i++) {
        if (integerMap.getOrDefault(nums2[i], 0) > 0) {
            resultList.add(nums2[i]);
            // 减少HashMap中该元素的计数
            integerMap.put(nums2[i], integerMap.get(nums2[i]) - 1);
        }
    }
    // 使用Java 8 Stream API将ArrayList转换为数组
    return resultList.stream().mapToInt(Integer::intValue).toArray();
}

时间复杂度:O(m + n)

空间复杂度:O(m + n)

总结

那有同学可能问了,遇到哈希问题我直接都用 set 不就得了,用什么数组啊。

直接使用 set 不仅占用空间比数组大,而且速度要比数组慢,set 把数值映射到 key 上都要做 hash 计算的。

不要小瞧这个耗时,在数据量大的情况,差距是很明显的。