Set和Map数据结构

105 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

理论

Set和Map都是ES6新增的数据结构。

Set

类似于数组,但成员中没有重复值,都是唯一的。

Set本身是个构造函数,用来生成Set数据结构:

let set = new Set()

通过add方法向set集合中添加成员。

set.add(6)

Map

传统的对象key值只能是字符串。这带来了极大的限制,Map扩展了key值的类型范围,不再是仅用字符串。

和Set类似,Map本身也是构造函数,用来生成Map数据结构,添加键值对是通过set方法。

let map = new Map()
map.set('total', 100)
map.get('total') // 100

has方法来判断是否存在某个键值

map.has('total') // true

求两数之和

描述

给定一个数组和目标数,如:数组[2,4,6,7,9],目标数15,返回两个数的下标值,这里应该返回的就是[2,4]

分析

本题最容易想到的就是暴力破解法,用两层循环来查找,但对于数组长度很大的情况下,可能就耗时很长,不是最佳的解法。这样的解题方式时间复杂度是O(N²)。

如果想优化,那自然会想到我们仅用一层循环是否可以做到呢?

用我们上面说的Map结构是可以的,其实Map的键值对也是一种Hash结构。

思路是:单层循环最大时间复杂度O(N)这个肯定是必须要的,要不然可能没有完全遍历到。我们所要做的就是在单层循环的时候把遍历过的和未遍历的进行比较。这时候我们可以把遍历过的不断存入Map中,在往后遍历的过程中不断对比目标值减去当前遍历值是否存在于Map中,如果存在,则直接返回,就是想要找的两数,不存在,则继续往下执行。

代码

var twoSum = function(nums, target) {
  // 用于存入已遍历但未符合的值
  let map = new Map()
  for (let i = 0; i < nums.length; i++) {
    let x = target - nums[i]
    if (map.has(x)) {
      return [map.get(x), i]
    }
    map.set(nums[i], i)
  }
};