• ⑦ 数据结构之“字典”


    一、 理论

    1. 字典简介

    • 与集合类似,字典也是一种存储唯一值的数据结构,是以 键值对 的形式存储的
    • es6中有字典Map

    1.1 增

    const m = new Map()
    m.set('a', 'aa')
    m.set('b', 'bb')
    

    1.2 删

    m.delete('b')
    m.clear()
    

    1.3 改

    m.set('a', 'aaa')
    

    1.4 查

    m.get('a')
    

    二、刷题

    1. 两个数组的交集(349)

    1.1 题目描述

    • 给定两个数组,编写一个函数来计算它们的交集
    • 说明
      • 输出结果中的每个元素一定是唯一的
      • 我们可以不考虑输出结果的顺序

    1.2 解题思路

    输入:nums1 = [1,2,2,1], nums2 = [2,2]
    输出:[2]

    • 用字典建立一个映射关系,记录nums1里有的值
    • 遍历nums2,找出nums1中有的值

    1.3 解题步骤

    • 新建一个字典,遍历nums1,填充字典
    • 遍历nums2,遇到字典里有的值就选出并从字典中删除
    function intersection(nums1, nums2) {
      const map = new Map()
      nums1.forEach(item => map.set(item, true))
      const res = []
      nums2.forEach(item => {
        if(map.has(item)) {
          res.push(item)
          map.delete(item)
        }
      })
      return res
    }
    

    1.4 时间复杂度&空间复杂度

    • 时间复杂度:O(n+m)
    • 空间复杂度:O(n)

    2. 有效的括号(20)

    2.1 题目描述

    • 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效
    • 有效字符串需满足:
      • 左括号必须用相同类型的右括号闭合
      • 左括号必须以正确的顺序闭合

    2.2 解题思路

    输入:s = "()"
    输出:true

    2.3 解题步骤

    function isValid(s) {
      if(s.length % 2 == 1) return false
      const stack = []
      const map = new Map()
      map.set('(', ')')
      map.set('{', '}')
      map.set('[', ']')
      for(let i = 0; i < s.length; i++) {
        let c = s[i]
        if(map.has(c)) {
          stack.push(c)
        } else {
          const t = stack[stack.length-1]
          if(map.get(t) === c) {
            stack.pop()
          } else {
            return false
          }
        }
      }
      return stack.length == 0
    }
    

    2.4 时间复杂度&空间复杂度

    • 时间复杂度:O(n)
    • 空间复杂度:O(1)

    3. 两数之和(1)

    3.1 题目描述

    • 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标
    • 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现
    • 你可以按任意顺序返回答案

    3.2 解题思路

    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]

    • nums相亲者 target匹配条件
    • 用字典建立婚姻介绍所,存储相亲者的数字和下标

    3.3 解题步骤

    • 新建字典作为婚姻介绍所
    • 遍历nums写入字典
    function twoSum(s) {
      const map = new Map()
      for(let i = 0; i < nums.length; i++) {
        const n = nums[i]
        const n2 = target - n
        if(map.has(n2)) {
          return [map.get(n2), i]
        }
        map.set(n, i)
      }
    }
    

    3.4 时间复杂度&空间复杂度

    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    4. 无重复字符的最长子串(3)

    4.1 题目描述

    • 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度

    4.2 解题思路

    输入:s = "abcabcbb"
    输出:3

    • 先找出所有不包含重复字符的子串
    • 找出最长的子串,返回其长度

    4.3 解题步骤

    • 双指针维护滑动窗口
    • 不断移动右指针,遇到重复字符,就把左指针移动到重复字符的下一位
    • 移动过程中记录所有窗口的长度并返回最大值
    function lengthOfLongestSubstring(s) {
      let l = 0
      let res = 0
      const map = new Map()
      for(let r = 0; r < s.length; r++) {
        if(map.has(s[r]) && map.get(s[r] >= l)) {
          l = map.get(s[r])+1
        }
        res = Math.max(res, r - l + 1)
        map.set(s[r], r)
      }
    }
    

    4.4 时间复杂度&空间复杂度

    • 时间复杂度:O(n)
    • 空间复杂度:O(m)

    5. 最小覆盖子串(76)

    5.1 题目描述

    • 给你一个字符串 s 、一个字符串 t
    • 返回 s 中涵盖 t 所有字符的最小子串
    • 如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
    • 注意
      • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量
      • 如果 s 中存在这样的子串,我们保证它是唯一的答案

    5.2 解题思路

    输入:s = "ADOBECODEBANC", t = "ABC"
    输出:"BANC"

    • 先找出所有包含t的子串
    • 找出最长的子串,返回其长度

    5.3 解题步骤

    • 双指针维护滑动窗口
    • 不断移动右指针,找到包含t的子串,移动左指针,尽量减少包含t的子串的长度
    function minWindow(s, t) {
      let l = 0, r = 0
      const need = new Map()
      for(let c of t) {
        need.set(c, need.has(c) ? need.get(c)+1 : 1)
      }
      let needType = need.size
      let res = ''
      while(r < s.length) {
        const c = s[r]
        if(need.get(c)) {
          need.set(c, need.get(c)-1)
          if(need.get(c) == 0) needType--
        }
        while(needType == 0) {
          const newRes = s.substring(l, r+1)
          if(!res || newRes.length < res.length) res = newRes
          const c2 = s[l]
          if(need.has(c2)) {
            need.set(c2, need.get(c2)+1)
            if(need.get(c2) == 1) needType++
          }
          l++
        }
        r++
      }
    }
    

    5.4 时间复杂度&空间复杂度

    • 时间复杂度:O(m+n)
    • 空间复杂度:O(m)

    三、总结 -- 技术要点

    • 与集合类似,字典也是一种存储唯一值的数据结构,是以 键值对 的形式存储的
    • es6中有字典Map
    • 字典常用操作:键值对的增删改查
  • 相关阅读:
    leetcode 买卖股票的最佳时机3
    leetcode 买卖股票的最佳时机Ⅱ
    leetcode 最长有效括号
    C++中的%lld和%I64d区别
    Ural 1095 Nikifor 3 思维+同余性质的利用
    博弈基础
    ural 1091. Tmutarakan Exams
    容斥原理
    一些易错的地方
    codeforces911D Inversion Counting 求逆序数+小trick
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15826466.html
Copyright © 2020-2023  润新知