集合:一种无序且唯一的数据结构
栈(后进先出)队列(先进先出)链表(next指针)都是有序的数据结构
集合中的元素都是唯一的。栈、队列、链表中的元素都可以重复。
在ES6中新加了集合,名为set.所以可以直接在JS中使用。
集合的常用操作
1、去重(比如给数组去重,直接给他转换为集合)
2、判断元素是否在集合中
3、求交集
//去重
const arr = [1, 1, 2, 2, 3, 3]
//实例化一个set对象,把arr传进去,加...[]变为数组
const arr2 = [...new Set(arr)]
arr2 = [1,2,3]
//判断元素是否在集合中
//set 的has方法
const set = new Set(arr);
const has = set.has(4)
//has === true
//求交集
const set2 = new Set([2, 3, 4]);
//set没有提供方法所以我们要转化成数组再求交集,
//1、把set变为数组 2、调用filter 筛选出set2也有的值,最终得到的数组再 new Set 把他实例化成新的集合
const set3 = new Set([...set].filter(item => set2.has(item)))
leetcod349 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。
输出结果中的每个元素一定是 唯一 的。
我们可以 不考虑输出结果的顺序 。
解题思路:无序且唯一,所以考虑到使用集合。
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersection = function(nums1, nums2) {
const set2 = new Set(nums2) //将nums2 变为集合
//通过数组的filter来筛选与set2中的交集,再变为集合去重,
const nums3 = new Set(nums1.filter(item => set2.has(item)))
//再变为数组 并return
const nums4 = [...nums3]
return nums4
};
另一种解法,用的数组原生includes
新思路 用集合对nums1去重
遍历nums1筛选出nums2也包含的值
return [...new Set(nums1)].filter(n=>nums2.includes(n))
时间复杂度:里面有一个filter循环,同时还进行了includes操作,两个时间复杂度都是O(n),也就是一个嵌套 所以时间复杂度是 O (m*n)m就是去重后数组的长度,n是nums2的长度
空间复杂度:nums1/2都是已有的存储 额外的就是这个去重后的nums1这个数组
O(m)m就是去重后数组的长度
前端与集合:ES6中的Set
Set操作
使用Set对象:new(实例化) add delete has size
let mySet = new Set()
add
mySet.add(1)
Set(1) {1}
mySet.add(5)
Set(2) {1, 5}
mySet.add(5)
Set(2) {1, 5}
mySet.add('fuck')
Set(3) {1, 5, 'fuck'}
let o = {a:777}
mySet.add(o)
Set(4) {1, 5, 'fuck', {…}}
mySet.add({a:777})
Set(5) {1, 5, 'fuck', {…}, {…}}
两个对象看起来一样但是再内存中存储的位置不同,本质上是两个不同的对象。
has
mySet.has('1')
false
mySet.has(1)
true
mySet.has(o)
true
delete
Set(5) {1, 5, 'fuck', {…}, {…}}
mySet.delete(5)
Set(4) {1, 'fuck', {…}, {…}}
size获取当前集合的尺寸 也就是长度把
迭代Set: 多种迭代方法、Set与Array互转、求交集、差集
迭代方法
for(let n of mySet){console.log(n)}
1
5
fuck
{a: 777}
{a: 777}
for(let n of mySet.keys()){console.log(n)}
for(let n of mySet.values()){console.log(n)}
都可以迭代出来,所以对于Set Keys和Value是一样的
for(let[key,value] n of mySet.entries()){console.log(key,value)}
使用entries方法可以看出他们是一模一样的
entries() 方法返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。
Set与Array互转
Set转数组
const myArr = [...mySet]
const myArr = Array.from(mySet)
数组转Set
const mySet2 = new Set(myArr)
求交集
const set2 = new Set([2, 3, 4]);
//set没有提供方法所以我们要转化成数组再求交集,
//1、把set变为数组 2、调用filter 筛选出set2也有的值,最终得到的数组再 new Set 把他实例化成新的集合
const set3 = new Set([...set].filter(item => set2.has(item)))
差集
set1
set2
求set2中没set1中有的值
const difference = new Set([...set].filter(item => !set2.has(item)))
就加一个感叹号代表否定
```以