350.两个数组的交集Ⅱ
难度:简单
给你两个整数数组 nums1
和 nums2
,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 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 计算的。
不要小瞧这个耗时,在数据量大的情况,差距是很明显的。