两个数组的交集 II
给你两个整数数组 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]
思路
使用 Hash 表解决这道题目:
- 预处理 Hash 表:记录 num1 中每一个元素出现的次数。
- 遍历 nums2:对每个 nums2 中的元素,如果它存在于 nums1 中并且 count > 0,则将该元素添加进交集当中,并更新 Hash 表。
- 返回交集结果:返回一个包含交集元素的数组,且每个元素的出现次数与在原始数组中的出现次数一致。
class Solution {public int[] intersect(int[] nums1, int[] nums2) {// 如果 nums1 的长度大于 nums2 的长度,则交换 nums1 和 nums2,以减少遍历次数// 因为我们可以先遍历较小的数组,这样可以优化性能if (nums1.length > nums2.length) {return intersect(nums2, nums1); // 递归调用,交换两个数组}// 创建一个哈希表 map,用来记录 nums1 中每个元素的出现次数Map<Integer, Integer> map = new HashMap<>();// 遍历 nums1,统计每个数字出现的次数for (int num : nums1) {// 获取当前 num 在 map 中的出现次数(若不存在则默认为 0),然后将其次数加 1int count = map.getOrDefault(num, 0) + 1;// 将 num 和更新后的计数存入哈希表map.put(num, count);}// 创建一个数组 intersection,用于存储交集元素// 最多会有 nums1.length 个元素,所以数组大小为 nums1.lengthint[] intersection = new int[nums1.length];// index 变量记录当前交集数组的插入位置int index = 0;// 遍历 nums2,查找其中与 nums1 的交集for (int num : nums2) {// 获取 num 在 map 中的出现次数(如果不存在,默认返回 0)int count = map.getOrDefault(num, 0);// 如果 num 出现次数大于 0,表示它是交集的一部分if (count > 0) {// 将 num 加入交集数组,并更新交集数组的插入位置intersection[index++] = num;// 将 num 在 map 中的计数减 1,表示已经使用一个该元素count--;// 如果该元素的计数仍大于 0,则更新哈希表if (count > 0) {map.put(num, count);} else {// 如果该元素的计数为 0,则从哈希表中移除该元素map.remove(num);}}}// 使用 Arrays.copyOfRange 返回交集数组的有效部分,长度为 indexreturn Arrays.copyOfRange(intersection, 0, index);}
}