小五的算法系列 - 集合与字典 (Set & Map)

563 阅读2分钟

Hello, 各位勇敢的小伙伴, 大家好, 我是你们的嘴强王者小五, 身体健康, 脑子没病.

本人有丰富的脱发技巧, 能让你一跃成为资深大咖.

一看就会一写就废是本人的主旨, 菜到抠脚是本人的特点, 卑微中透着一丝丝刚强, 傻人有傻福是对我最大的安慰.

欢迎来到小五算法系列集合与字典 (Set & Map).

前言

此系列文章以《算法图解》和《学习JavaScript算法》两书为核心,其余资料为辅助,并佐以笔者愚见所成。力求以简单、趣味的语言带大家领略这算法世界的奇妙。

other37.gif

集合 - Set

🦅 特点:无序且唯一

模拟实现

我们用js模拟一个集合,并为其添加如下方法:

  • add(element):添加元素

  • delete(element):删除元素

  • has(element):元素是否在集合中

  • clear():清空集合

  • size():集合中元素个数

  • values():返回包含集合中所有元素的数组

set1.png

数组去重

“无序且唯一” 这和把去重两字印在脸上有什么区别

  • 扩展运算符内部逻辑是for...of,可对 Set 进行解构

  • Array.from方法可将 Set 结构转为数组

[...new Set(arr)]; // 扩展运算符
Array.from(new Set(arr)); // Array.from

集合操作

我们来实现下集合的几种操作:并集、交集、差集、子集

🦅 并集

公式:AB={xxAxB}A∪B=\{x|x∈A∨x∈B\}

set2.png

const unionSet = (
  set1: Set<unknown>, set2: Set<unknown>
) => {
  return new Set([...set1, ...set2]);
}

🦅 交集

公式:AB={xxAxB}A∩B=\{x|x∈A∧x∈B\}

set3.png

const intersection = (
  set1: Set<unknown>, set2: Set<unknown>
) => {
  return new Set(
    [...set1].filter(
      item => set2.has(item)
    )
  );
}

🦅 差集

公式:AB={xxAxB}A−B=\{x|x∈A∧x∉B\}

set4.png

const difference = (
  set1: Set<unknown>, set2: Set<unknown>
) => {
  return new Set(
    [...set1].filter(
      item => !set2.has(item)
    )
  );
}

🦅 子集

公式:AB={xxAxB}A⊆B=\{x|x∈A→x∈B\}

set5.jpeg

const subSet = (
  set1: Set<unknown>, set2: Set<unknown>
) => {
  for (let item of set1) {
    if (!set2.has(item)) return false;
  }
  return true;
}

字典 - Map

🦅 类对象,键值对形式的集合

模拟实现

我们用 js对象 模拟一个简易版的字典,其 keystring 类型,并为其添加如下方法:

  • set(key, value):添加元素

  • get(key):获取元素

  • remove(key):移除元素

  • has(key):元素是否在字典中

  • clear():清空字典

  • size():字典中元素个数

  • keys():返回字典中所有key组成的数组

  • values():返回字典中所有value组成的数组

map1.png

🦅 ES6 Map 补充说明

其“键”可为任何类型的值,并不仅是字符串

const arr = [1, 2, 3];
const map = new Map([[arr, '黄刀小五'], [arr, '二狗子']]);

map2.png

注意,只有对同一个对象的引用,Map 结构才将其视为同一个键

const map = new Map([[[1,2,3], '黄刀小五'], [[1,2,3], '二狗子']]);

map3.png

两数之和

map4.png

  • 循环过程中,用 Map 将数组的值及下标存入

  • 若 target - current 在 Map 中存在,取出下标

const twoSum = (
  nums: number[], target: number
): number[] => {
  const map = new Map();
  for (let i = 0; i < nums.length; i++) {
    let find = target - nums[i];
    if (map.has(find)) {
      return [map.get(find), i];
    } else {
      map.set(nums[i], i);
    }
  }
  return [];
}

后记

🔗 本系列其它文章链接:

🔗 参考链接:阮一峰 - ECMAScript 6 入门 - Set 和 Map 数据结构

other29.gif