学透哈希表 Leetcode:349

87 阅读2分钟

JavaScript中使用Set优化数组交集算法

问题背景

LeetCode 349题要求找出两个数组的交集,且结果中的每个元素必须是唯一的。传统方法可能需要多层循环嵌套,时间复杂度较高。本文介绍如何利用ES6的Set数据结构实现高效解法。

Set数据结构特性

  1. 自动去重:Set会自动过滤重复值,确保集合中的元素唯一
  2. 高效查找has()方法时间复杂度为O(1),远优于数组的includes()
  3. 常用方法
    • 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];
}

性能优化点

  1. 预处理去重
const set1 = new Set(nums1);
const set2 = new Set(nums2);
  1. 遍历优化:总是遍历较小的Set,减少循环次数
  2. 空间换时间:使用额外空间存储Set,换取O(1)的查找效率

复杂度分析

  • 时间复杂度:O(m+n),其中m和n是两个数组的长度
  • 空间复杂度:O(m+n),存储两个Set所需空间

实际应用场景

  1. 用户标签系统:找出两个用户的共同标签
  2. 商品推荐系统:寻找用户偏好的交集
  3. 数据分析:统计多组数据的共同特征

对比传统方法

// 传统双重循环方法 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;
}

扩展思考

  1. 如果数组已排序,可以使用双指针法进一步优化
  2. 处理大数据量时,可考虑分治策略
  3. 对于非基本类型数据,需要自定义hash函数

总结

利用Set数据结构解决数组交集问题,既简洁又高效,体现了ES6现代JavaScript语法的优势。掌握这种解题思路,可以应对类似的算法问题,提升代码性能。