javascript算法之字典 必出精品

193 阅读2分钟

1、介绍

var m = new Map();
    //增
    m.set('a', 'aa'); //保存key-value对
    // console.log(m);
    m.set('b', 'bb');
    console.log(m) //Map(2) {"a" => "aa", "b" => "bb"}
    
  	// 可以使用 m.get('a')获取 a属性的 value值  
    var p = m.get('a')
    console.log(p) //aa
m.delete('b')  // 删除了 key-->b 对应的value也没了
console.log(m)  //Map(1) {"a" => "aa"} 

m.clear()
console.log(m) //Map(0) {} 删除所有的内容   
// 改  可使用set 覆盖
    m.set('a', '666') // 将原本的 'aa' 改成了 'aaa'
    console.log(m) //Map(1) {"a" => "666"} 
// 可以使用 m.get('a')获取 a属性的 value值  
    var p = m.get('a')
    console.log(p) //aa

2、leetcode 349两个数组交集

    // 时间复杂度 O(M * N ) 空间 复杂度O(M) M表示num1长度 N表示num2长度
// 求数组交集 字典解法
    var intersection = function (num1, num2) {
        // 新建一个字典
        var map = new Map();
        // 遍历第一个数组 并把值放进去 值为true表示放进字典内
        num1.forEach(n => {
            map.set(n, true)
        });
        // 初始化结果 数组
        const res = [];
        // 遍历第二个数组
        num2.forEach(n => {
            // 判断 也出现的值
            if (map.get(n)) {
                //  放进新数组就是交集部分
                res.push(n);
                // 需要立即从字典删除避免得到的结果重复
                map.delete(n);
            }
        })
        return res
    }
    var test = intersection([1, 2, 3, 4], [1, 2]);
    console.log(test)

3、leetcode 20 有效的括号

// 时间复杂度 O(n) 空间复杂度 O(n)
  //方法二  使用 字典 优化 
   var isValid = function (s) {
    if (s.length % 2 === 1) {
        return false
    }
    // 定义栈
    const stack = []
    const map = new Map()
    map.set('(',')')
    map.set('[',']')
    map.set('{','}')
    // 遍历
    for (var i = 0; i < s.length; i++) {
        const c = s[i]
        if (map.has(c)) {
            stack.push(c)
        } else {
            const top = stack[stack.length - 1]
            if (map.get(top) === c) {
                stack.pop()
            } else {
                return false
            }
        }
    }
    return stack.length === 0
} 

4、leetcode 1 两数字之和

// leetcode 1 求两个数之和
    var twoSum = function (nums, target) {
        var map = new Map()
        for (var i = 0; i < nums.length; i++) {
            const n = nums[i]; // 拿到每个数组值
            const n2 = target - n; // 匹配值
            // 匹配到之后  拿到两个的下标
            if (map.has(n2)) {
                return [map.get(n2), i]
                //没有匹配上 则 先将值和下标存在map中
            } else {
                map.set(n, i)
            }
        }
    }

    var test = twoSum([1, 2, 3, 6], 9)
    console.log(test) // [2,3]

5、leetcode 3 无重复字符的最长子串

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

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

//   时间复杂度O(n) n表示s.length 空间复杂度 O(m)  m是字符串 不重复字符个数
var lengthOfLongestSubstring = function (s) {
      // 新建两个移动指针 l r
      let l = 0;
      // 初始化结果
      let res = 0;
      // 新建字典 
      const map = new Map();
      for (var r = 0; r < s.length; r++) {
          // 如果字典中 再次出现右指针指向的东西
          //map.get(s[r] >= l  防错误
          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)
      }
      return res;
  }

6、 leetcode 76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

    // leetcode 76  最小覆盖长度
    //时间复杂度 O(m + n) 空间复杂度 O(k)
    var minWindow = function (s, t) {
        // 新建两个移动指针
        var l = 0;
        var r = 0;
        // 新建一个字典
        var need = new Map();
        // 循环遍历 t 
        for (let c of t) {
            need.set(c, need.has(c) ? need.get(c) + 1 : 1)
        }
        // console.log(need)    //Map(3) {"A" => 1, "B" => 1, "C" => 1}

        // 字典长度 赋给t 中的需求类型 
        let needType = need.size;
        // 初始化结果
        let res = "";
        while (r < s.length) {
            // 找到 t中匹配的每个字符后 减一 找剩下的
            // 遍历右 指针
            const c = s[r];
            if (need.has(c)) {
                need.set(c, need.get(c) - 1);
                if (need.get(c) === 0) {
                    needType -= 1
                }
            }
            // 当 t中的都找到了 需要缩小范围
            while (needType === 0) {
                // console.log(s.substring(l, r + 1))
                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 += 1
                    }
                }
                l += 1;
            }
            r = r + 1;
        }

        return res
    }

7、小结