0350. 两个数组的交集 II【简单】
1. 📝 题目描述
给你两个整数数组 nums1 和 nums2,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
txt
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]1
2
2
示例 2:
txt
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]1
2
2
提示:
1 <= nums1.length, nums2.length <= 10000 <= nums1[i], nums2[i] <= 1000
进阶:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
- 如果
nums1的大小比nums2小,哪种方法更优? - 如果
nums2的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
2. 🎯 s.1 - 哈希表统计法(推荐)
js
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersect = function (nums1, nums2) {
// 优化:让较小的数组构建哈希表
if (nums1.length > nums2.length) {
return intersect(nums2, nums1)
}
// 使用哈希表统计 nums1 中每个元素的出现次数
const map = new Map()
for (const num of nums1) {
map.set(num, (map.get(num) || 0) + 1)
}
const result = []
// 遍历 nums2,查找交集
for (const num of nums2) {
if (map.has(num) && map.get(num) > 0) {
result.push(num)
map.set(num, map.get(num) - 1) // 减少计数
}
}
return result
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- 时间复杂度:
,其中 m 和 n 分别是两个数组的长度 - 空间复杂度:
,哈希表最多存储较小数组的元素
3. 🎯 s.2 - 排序 + 双指针
js
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersect = function (nums1, nums2) {
// 先对两个数组排序
nums1.sort((a, b) => a - b)
nums2.sort((a, b) => a - b)
const result = []
let i = 0,
j = 0
// 使用双指针查找交集
while (i < nums1.length && j < nums2.length) {
if (nums1[i] < nums2[j]) {
i++
} else if (nums1[i] > nums2[j]) {
j++
} else {
// 找到交集元素
result.push(nums1[i])
i++
j++
}
}
return result
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- 时间复杂度:
,主要是排序的时间复杂度 - 空间复杂度:
,不考虑输出数组
4. 🎯 s.3 - 使用内置方法(简洁但效率较低)
js
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersect = function (nums1, nums2) {
const result = []
for (const num of nums1) {
const index = nums2.indexOf(num)
if (index !== -1) {
result.push(num)
nums2.splice(index, 1) // 移除已匹配的元素
}
}
return result
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 时间复杂度:
,最坏情况下需要多次查找和删除 - 空间复杂度:
,不考虑输出数组