JavaScript中使用Set优化数组交集算法
问题背景
LeetCode 349题要求找出两个数组的交集,且结果中的每个元素必须是唯一的。传统方法可能需要多层循环嵌套,时间复杂度较高。本文介绍如何利用ES6的Set数据结构实现高效解法。
Set数据结构特性
- 自动去重:Set会自动过滤重复值,确保集合中的元素唯一
- 高效查找:
has()方法时间复杂度为O(1),远优于数组的includes() - 常用方法:
add(value)添加元素delete(value)删除元素size属性获取元素数量
算法实现解析
const set_intersection = (set1, set2) => {
// 优化:总是遍历较小的Set
if (set1.size > set2.size) {
return set_intersection(set2, set1);
}
const intersection = new Set();
for (const num of set1) {
if (set2.has(num)) {
intersection.add(num);
}
}
return [...intersection];
}
性能优化点
- 预处理去重:
const set1 = new Set(nums1);
const set2 = new Set(nums2);
- 遍历优化:总是遍历较小的Set,减少循环次数
- 空间换时间:使用额外空间存储Set,换取O(1)的查找效率
复杂度分析
- 时间复杂度:O(m+n),其中m和n是两个数组的长度
- 空间复杂度:O(m+n),存储两个Set所需空间
实际应用场景
- 用户标签系统:找出两个用户的共同标签
- 商品推荐系统:寻找用户偏好的交集
- 数据分析:统计多组数据的共同特征
对比传统方法
// 传统双重循环方法 O(n^2)
function intersection(nums1, nums2) {
const result = [];
for (let i = 0; i < nums1.length; i++) {
for (let j = 0; j < nums2.length; j++) {
if (nums1[i] === nums2[j] && !result.includes(nums1[i])) {
result.push(nums1[i]);
}
}
}
return result;
}
扩展思考
- 如果数组已排序,可以使用双指针法进一步优化
- 处理大数据量时,可考虑分治策略
- 对于非基本类型数据,需要自定义hash函数
总结
利用Set数据结构解决数组交集问题,既简洁又高效,体现了ES6现代JavaScript语法的优势。掌握这种解题思路,可以应对类似的算法问题,提升代码性能。