Set

JavaScript中的Set是一种内建的数据结构,类似于数组,但具有以下几个特点:

  1. 元素唯一性Set中的每个元素都是唯一的,不允许重复。
  2. 顺序性:元素按插入顺序排序。
  3. 可迭代性Set是可迭代的,可以使用for...of进行遍历。
  4. 值类型Set只关心元素的值是否相等,而不关心其类型。

创建一个Set

1
let mySet = new Set();

可以通过传入一个可迭代对象来初始化一个Set

1
2
let numbers = new Set([1, 2, 3, 4]);
console.log(numbers); // Set { 1, 2, 3, 4 }
  1. 元素唯一性
    Set 中的所有元素都是唯一的,不能重复。例如:

    1
    2
    const mySet = new Set([1, 2, 2, 3]);
    console.log(mySet); // 输出:Set(3) { 1, 2, 3 }
  2. 可以接受可迭代对象(例如数组)作为参数
    创建 Set 时,可以直接将一个数组或其他可迭代对象传入:

    1
    2
    3
    const numbers = [1, 2, 3, 4];
    const mySet = new Set(numbers);
    console.log(mySet); // 输出:Set(4) { 1, 2, 3, 4 }

常用方法

  1. add(value): 向Set中添加一个新的元素,如果元素已经存在则不会添加。
1
2
3
4
mySet.add(1);
mySet.add(2);
mySet.add(1); // 不会添加重复的1
console.log(mySet); // Set { 1, 2 }
  1. delete(value): 从Set中删除一个元素。如果元素不存在,返回false;如果删除成功,返回true
1
2
mySet.delete(2);
console.log(mySet); // Set { 1 }
  1. has(value): 判断Set中是否存在某个元素,返回布尔值。
1
2
console.log(mySet.has(1));  // true
console.log(mySet.has(3)); // false
  1. clear(): 清空Set中的所有元素。
1
2
mySet.clear();
console.log(mySet); // Set {}
  1. size: 获取Set中元素的个数。
1
2
let mySet = new Set([1, 2, 3]);
console.log(mySet.size); // 3

迭代Set

Set是可迭代的,可以使用for...of进行遍历,或者使用forEach()方法。

  1. for…of: 按照插入顺序遍历Set中的元素。
1
2
3
4
let mySet = new Set([1, 2, 3]);
for (let value of mySet) {
console.log(value); // 1, 2, 3
}
  1. forEach(): 对Set中的每个元素执行提供的回调函数。
1
2
3
mySet.forEach((value, valueAgain, set) => {
console.log(value); // 1, 2, 3
});

注意事项

  • 元素比较Set中的元素是根据SameValueZero规则进行比较的,这意味着NaN等同于NaN+0-0是不同的。
  • 性能Set通常比数组具有更好的查找性能,特别是在需要频繁检查元素是否存在时。

适用场景

  • 去重Set特别适用于去重操作。

    1
    2
    3
    let array = [1, 2, 3, 1, 2, 4];
    let uniqueArray = [...new Set(array)];
    console.log(uniqueArray); // [1, 2, 3, 4]
  • 集合运算:可以很容易地实现集合之间的交集、并集和差集等操作。

并集(Union)

1
2
3
4
let set1 = new Set([1, 2, 3]);
let set2 = new Set([3, 4, 5]);
let union = new Set([...set1, ...set2]);
console.log(union); // Set { 1, 2, 3, 4, 5 }

交集(Intersection)

1
2
let intersection = new Set([...set1].filter(x => set2.has(x)));
console.log(intersection); // Set { 3 }

差集(Difference)

1
2
let difference = new Set([...set1].filter(x => !set2.has(x)));
console.log(difference); // Set { 1, 2 }

总结

  • Set提供了一个便捷的方式来存储不重复的元素。
  • 它支持高效的插入、查找和删除操作。
  • 适用于去重和集合运算等场景。

题目

142. 环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
const set = new Set()
let current = head
while(current){
if(set.has(current)){
return current
}
set.add(current)
current = current.next
}
return null
};

相交链表

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

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
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function(headA, headB) {
let setarr = new Set()
let number1 = headA
while(number1!==null){
setarr.add(number1)
number1=number1.next;
}
let number2 = headB
while(number2!==null){
if(setarr.has(number2)){
return number2
}
number2=number2.next
}
return null
};