哈希表 - 两个数组的交集(集合、数组) - JS

一、Set基础

在 JavaScript 中,Set 是一种集合(Collection)​ 数据结构,用于存储唯一值 ​(不允许重复),并且可以高效地进行添加、删除、查询 等操作。它类似于数组(Array),但成员的值都是唯一的,没有重复项。


1. Set 的基本特性

  • 存储唯一值Set 不会存储重复的值,如果尝试添加重复值,会被自动忽略。
  • 无序存储Set 中的元素没有索引,遍历顺序与插入顺序一致,但不支持索引访问(如 set[0])。
  • 可迭代 :可以使用 for...offorEach 遍历 Set 中的元素。
  • 支持任意数据类型 :可以存储 numberstringobjectfunction 等,但 NaNundefined 也可以被存储。

2. 创建 Set

复制代码
const mySet = new Set(); // 空 Set
const mySet2 = new Set([1, 2, 3, 4, 4, 5]); // 自动去重,最终存储 [1, 2, 3, 4, 5]

3. Set 的常用方法

方法 描述 示例
add(value) 添加一个值,返回 Set 本身(可链式调用) mySet.add(10).add(20)
delete(value) 删除某个值,返回 boolean(是否删除成功) mySet.delete(1)
has(value) 检查 Set 是否包含某个值,返回 boolean mySet.has(2)
clear() 清空 Set mySet.clear()
size 返回 Set 的元素个数(类似 Array.length mySet.size

示例:​

复制代码
const set = new Set();

set.add(1); // Set { 1 }
set.add(2); // Set { 1, 2 }
set.add(2); // 重复值,被忽略
set.add("hello"); // Set { 1, 2, "hello" }

console.log(set.size); // 3
console.log(set.has(1)); // true
set.delete(1); // true
console.log(set.has(1)); // false

4. Set 的遍历方法

Set 是可迭代的,可以使用以下方式遍历:

​**(1) for...of 循环**

复制代码
const set = new Set([1, 2, 3]);

for (const item of set) {
  console.log(item); // 1, 2, 3
}

​**(2) forEach 方法**

复制代码
set.forEach((value) => {
  console.log(value); // 1, 2, 3
});

​**(3) 转换成数组(Array.from[...set])​**

复制代码
const arr = Array.from(set); // [1, 2, 3]
const arr2 = [...set]; // [1, 2, 3]

5. Set 的应用场景

​**(1) 数组去重**

复制代码
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3, 4, 5]

​**(2) 判断元素是否存在(比 Array.includes 更快)​**

复制代码
const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true

​**(3) 存储非重复对象(需注意引用类型)​**

复制代码
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
const set = new Set([obj1, obj2, obj1]); // 存储 obj1 和 obj2(obj1 只存一次)

​**(4) 数学集合运算(并集、交集、差集)​**

复制代码
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);

// 并集
const union = new Set([...setA, ...setB]); // Set {1, 2, 3, 4}

// 交集
const intersection = new Set([...setA].filter(x => setB.has(x))); // Set {2, 3}

// 差集(A - B)
const difference = new Set([...setA].filter(x => !setB.has(x))); // Set {1}

6. Set 与 Array 的区别

特性 Set Array
唯一性 不允许重复值 允许重复值
索引访问 不支持 set[0] 支持 arr[0]
查找效率 has() 是 O(1) includes() 是 O(n)
顺序 插入顺序 索引顺序
方法 add() / delete() push() / pop()

7. 注意事项

  • NaNSet 中被认为是相同的值:

    复制代码
    const set = new Set();
    set.add(NaN);
    set.add(NaN); // 只会存一个 NaN
  • Set 存储对象时,比较的是引用 而非值:

    复制代码
    const obj1 = { a: 1 };
    const obj2 = { a: 1 };
    set.add(obj1);
    set.add(obj2); // 会存储两个对象,因为引用不同

总结

  • Set 是一种存储唯一值 的集合,适用于去重、快速查找、集合运算等场景。
  • 主要方法:add()delete()has()clear()size
  • 遍历方式:for...offorEach[...set]
  • 相比数组,Set去重和查找方面更高效,但不支持索引访问。

如果你需要存储不重复的值,并且希望高效地判断某个值是否存在,Set 是一个很好的选择!

二、349.两个数组的交集

给定两个数组 nums1nums2 ,返回 它们的 输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

示例 1:

复制代码
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

复制代码
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

方法 1:使用 Set 去重 + 遍历查找

javascript 复制代码
function intersection(nums1, nums2) {
    const set1 = new Set(nums1);
    const set2 = new Set(nums2);
    const result = [];

    for (const num of set1) {
        if (set2.has(num)) {
            result.push(num);
        }
    }

    return result;
}

方法 2:使用 Set + Array.filter

javascript 复制代码
function intersection(nums1, nums2) {
    const set1 = new Set(nums1);
    const set2 = new Set(nums2);
    return [...set1].filter(num => set2.has(num));
}

方法 3:仅使用 Set + Array.includes(适用于小规模数据)​

javascript 复制代码
function intersection(nums1, nums2) {
    const uniqueNums1 = [...new Set(nums1)];
    return uniqueNums1.filter(num => nums2.includes(num));
}

总结

  • 使用 Set 去重 是解决此类问题的关键。
  • 遍历查找交集 时,Set.has()Array.includes() 更高效(O(1) vs O(n))。
  • 返回结果顺序不重要,因此直接返回过滤后的数组即可。

350. 两个数组的交集 II

给你两个整数数组 nums1nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:

复制代码
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

示例 2:

复制代码
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

需要统计次数,就需要用上数组了。也可以用map 但还没复习到,后续会更新。

javascript 复制代码
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let hashs = new Array(1001).fill(0);
    let result=[];
    for(let i=0;i<nums1.length;i++){
        hashs[nums1[i]]++;
    }
    for(let i=0;i<nums2.length;i++){
        if(hashs[nums2[i]]>0) {
         result.push(nums2[i]);
         hashs[nums2[i]]--;  
        }
    }
    return result;
};
相关推荐
zandy10119 分钟前
如何快速入门-衡石科技分析平台
服务器·前端·科技·数据库管理员
邝邝邝邝丹42 分钟前
React学习———React Router
前端·学习·react.js
Yvonne爱编码1 小时前
CSS- 2.1 实战之图文混排、表格、表单
前端·css·html·github·状态模式·html5·hbuilder
前端小巷子1 小时前
CSS面试题汇总
前端·css·面试
绝美焦栖1 小时前
vue复杂数据类型多层嵌套的监听
前端·javascript·vue.js
xixixin_2 小时前
【Vite】前端开发服务器的配置
服务器·前端·网络
.生产的驴2 小时前
Vue3 加快页面加载速度 使用CDN外部库的加载 提升页面打开速度 服务器分发
运维·服务器·前端·vue.js·分布式·前端框架·vue
史迪仔01122 小时前
Python生成器:高效处理大数据的秘密武器
前端·数据库·python
蓝婷儿3 小时前
前端面试每日三题 - Day 34
前端·面试·职场和发展
CopyLower3 小时前
苹果计划将AI搜索集成至Safari:谷歌搜索下降引发的市场变革
前端·人工智能·safari