什么是字典

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

  1. const m = new Map()
  2. //增,改
  3. m.set('a', 'aa')
  4. //删
  5. m.delete('a')
  6. m.clear()

leetcode 349

解题思路

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

    代码

    1. /**
    2. * @param {number[]} nums1
    3. * @param {number[]} nums2
    4. * @return {number[]}
    5. * 时间复杂度O(m + n)
    6. * 空间复杂度O(n)
    7. */
    8. var intersection = function(nums1, nums2) {
    9. const map = new Map()
    10. nums1.forEach(item=>{
    11. map.set(item, true)
    12. })
    13. const res = []
    14. nums2.forEach(item=>{
    15. if(map.get(item)){
    16. res.push(item)
    17. map.delete(item)
    18. }
    19. })
    20. };

leetcode 20

解题思路

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

    代码

    1. var isValid = function(s) {
    2. const stack = [];
    3. const map = new Map()
    4. map.set('{', '}')
    5. map.set('[', ']')
    6. map.set('(', ')')
    7. for(let i = 0 ; i < s.length; i++) {
    8. const c = s[i]
    9. if(map.has(c)) {
    10. stack.push(c)
    11. } else {
    12. const t = stack[stack.length - 1];
    13. if(
    14. map.get(t) === c
    15. ) {
    16. stack.pop()
    17. } else {
    18. return false
    19. }
    20. }
    21. }
    22. return stack.length === 0
    23. };

    leetcode 1

    解题思路

  • 把nums想象成相亲者

  • target想象成匹配条件
  • 集合存储相亲双方的下标和值
  • 时间复杂度O(n)
  • 空间复杂度O(n)

    代码

    1. var twoSum = function(nums, target) {
    2. const map = new Map()
    3. for(let i = 0; i<nums.length; i++){
    4. const res = target - nums[i]
    5. if(map.has(res)) {
    6. return [map.get(res), i ]
    7. }
    8. map.set(nums[i], i)
    9. }
    10. };

    leetcode 3

    无重复字符的最长子串

    解题思路

  • 先找出所有无重复的子串

    • 用双指针维护一个滑动窗口,用来剪切子串
    • 不断移动右指针,遇到重复字符,就把左指针右移到重复字符下一位
    • 过程中记录所有窗口长度
  • 找出长度最大的子串
  • 时间复杂度O(n)
  • 空间复杂度O(m)

    代码

    1. var lengthOfLongestSubstring = function(s) {
    2. let start = 0
    3. let maxLength = 0
    4. const map = new Map()
    5. for(let end = 0; end < s.length; end ++){
    6. //拿到的左标,必须在滑动窗口内
    7. if(map.has(s[end]) && map.get(s[end]) >= start) {
    8. start = map.get(s[end]) + 1
    9. }
    10. maxLength = Math.max(maxLength, end - start + 1)
    11. map.set(s[end], end)
    12. }
    13. return maxLength
    14. };

leetcode 76

最小覆盖子串

  • 先找出所有覆盖子串
    • 用双指针维护一个滑动窗口,用来剪切子串
    • 不断移动右指针,找到包含T的子串,然后左指针右移,尽量减少包含T的子串长度
    • 过程中记录所有窗口长度
  • 找出符合要求的子串
  • 时间复杂度O(n + m)
  • 空间复杂度O(m)

    代码

    1. /**
    2. * @param {string} s
    3. * @param {string} t
    4. * @return {string}
    5. */
    6. var minWindow = function(s, t) {
    7. let start = 0
    8. let end = 0
    9. const map = new Map()
    10. // map 存储共有多少个不重复的字符
    11. // A: 1. B: 1. C:1
    12. for(let i = 0; i< t.length; i++) {
    13. map.set(t[i], map.get(t[i]) ? map.get(t[i]) + 1 : 1)
    14. }
    15. let res = ''
    16. let needType = map.size
    17. for(let i = 0; i< s.length; i++) {
    18. const c = s[i]
    19. if(map.has(c)) {
    20. map.set(c, map.get(c) - 1)
    21. if(map.get(c) ===0) {
    22. needType -= 1
    23. }
    24. }
    25. while(needType === 0){
    26. const sub = s.substring(start, end +1)
    27. if(!res || sub.length < res.length) {
    28. res = sub
    29. }
    30. const c2 = s[start]
    31. if(map.has(c2)) {
    32. map.set(c2, map.get(c2) + 1)
    33. if(map.get(c2) === 1) {
    34. needType +=1
    35. }
    36. }
    37. start ++;
    38. }
    39. end ++;
    40. }
    41. return res
    42. };