LeetCode 349: 两个数组的交集
题目描述:
给定两个数组,编写一个函数来计算它们的交集。
示例1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
示例2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]
解题思路
思路一: 利用两个Set
计算两个数组的交集,直观的方法是遍历数组 nums1,对于其中的每个元素,遍历数组 nums2 判断该元素是否在数组 nums2 中,如果存在,则将该元素添加到返回值。 实现代码如下:
const set_intersection = (set1, set2) => {
if (set1.size > set2.size) {
return set_intersection(set2, set1);
}
const intersection = new Set();
for (const num of set1) {
// 判断该元素是否在set2 中
if (set2.has(num)) {
intersection.add(num);
}
}
// 转换为数组
return [...intersection];
}
var intersection = function(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
return set_intersection(set1, set2);
};
时间复杂度:O(m+n); 其中 m 和 n 分别是两个数组的长度。使用两个集合分别存储两个数组中的元素需要 O(m+n) 的时间 空间复杂度:O(m+n); 其中 m 和 n 分别是两个数组的长度
思路三: 排序 + 双指针
- 两数组先进行排序: 利用sort方法;
- 创建intersection变量用于存放交集
- 两指针分别指向两数组的头部, 每次比较两个指针指向的两个数组中的数字
- 不相等,则指向较小数组指针右移;
- 相等,如果intersection数组为空或者值不等于intersection数组最后一个元素值,则push进结果,同时两指针都右移;
- 当至少有一个指针超出数组范围时,遍历终止;
实现代码如下:
var intersection = function(nums1, nums2) {
// 先进行排序
nums1.sort((x, y) => x - y);
nums2.sort((x, y) => x - y);
const length1 = nums1.length, length2 = nums2.length;
let index1 = 0, index2 = 0;
const intersection = [];
while (index1 < length1 && index2 < length2) {
const num1 = nums1[index1], num2 = nums2[index2];
if (num1 === num2) {
// 保证加入元素的唯一性
if (!intersection.length || num1 !== intersection[intersection.length - 1]) {
intersection.push(num1);
}
index1++;
index2++;
} else if (num1 < num2) {
index1++;
} else {
index2++;
}
}
return intersection;
};
时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度; 空间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度;
思路三:利用Set去重 + filter过滤
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersection = function(nums1, nums2) {
return [...new Set(nums1.filter((num) => nums2.includes(num)))]
};