350. 两个数组的交集 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]
常规解法
关键思路 - Map字符存储
- 用map存储数组每个元素的出现次数。
JS代码实现
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
const intersect = (nums1, nums2) => {
const result = [];
const map = new Map();
// 将nums1中的元素存入map中,key为元素,value为出现次数
for (const num of nums1) {
map.set(num, (map.get(num) || 0) + 1);
}
// 遍历nums2,如果map中有该元素,则将其加入result中,并将map中该元素的次数减1
for (const num of nums2) {
if(map.has(num) && map.get(num)){
result.push(num);
map.set(num, map.get(num) - 1);
}
}
return result;
};
复杂度分析
- 时间复杂度:O(m + n)
- 空间复杂度:O(min(m, n))
优化解法
关键思路 - 排序+双指针
- 先对两个数组进行排序,然后用双指针同时遍历两个数组。
- 该方法适用于已经排好序的数组。
JS代码实现
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
const intersect = (nums1, nums2) => {
const result = [];
nums1.sort((a, b) => a - b);
nums2.sort((a, b) => a - b);
let i = 0; // nums1的指针
let j = 0; // nums2的指针
while (i < nums1.length && j < nums2.length) {
if (nums1[i] === nums2[j]) {
result.push(nums1[i]);
i++;
j++;
} else if (nums1[i] < nums2[j]) {
i++;
} else {
j++;
}
}
return result;
};
复杂度分析
- 时间复杂度:O(m log m + n log n),主要是排序的开销
- 空间复杂度:O(log m + log n) 或 O(1),取决于排序算法的实现
结语
本文主要介绍了LeetCode第350题两个数组的交集II的两种解法,你还知道这题的其他解法吗?欢迎在评论区留言分享!