【JavaScript版数据结构与算法面向大厂面试】第七章 数据结构之“字典”

第七章 数据结构之“字典”

7.1 字典简介

  1. 存储唯一值、以键值对的方式存储数据。(映射)
  2. ES6中用Map表示字典
  3. 用的操作及代码:增set(),删delete()/clear(), 改set(), 查 get()。

const n = new Map();//实例化一个Map

//增 用编程的方式查看:VScode --> 调试中的(WATCH) --> 搜m.get(),如:m.get(“a”)
m.set(‘a’, ‘aa’);//建立键值对
m.set(‘b’, ‘bb’);//建立键值对

//删
m.delete(‘b’);//法一,只删除b
// m.clear();//法二,删除所有的键,即清空字典

//改
m.set(‘a’, ‘aaa’);

在这里插入图片描述

新建一个字典:
在这里插入图片描述

增加set():

用字典的set()方法来往字典中添加键值对,其中a为键,aa为值。

在这里插入图片描述
在这里插入图片描述

删除delete()/clear():

字典中有两个方法可以进行键值对的删除,其中delete()可以删除某个键值对,clear()是清除字典中的全部键值对。

在这里插入图片描述
修改set():

用覆盖的方式进行键值对的改变。
m.set(‘a’, ‘aaa’);

查找 get():

VScode --> 调试中的(WATCH) 用get()方法查找键a的值, 如:m.get(“a”)

在这里插入图片描述

7.2 Leetcode:349. 两个数组的交集

在这里插入图片描述

解题思路:

  1. 求nums1和nums2都有的值
  2. 用字典建立一个映射关系,记录nums1里有的值
  3. 遍历nums2找出nums1里也有的值

解题步聚:

  1. 新建一个字典,遍历nums1,填充字典
  2. 遍历nums2,遇到字典里的值就选出,并从字典中删除
/**
\* @param {number[]} nums1

\* @param {number[]} nums2

\* @return {number[]}

 */

var intersection = function (nums1, nums2) {
    const map = new Map();//新建一个字典
    nums1.forEach(n => {//遍历nums1里面的值,并把它填充到字典中建立映射关系
        map.set(n, true);
    });

    const res = []; // 声明一个空数组

    //遍历nums2里面的值,如果遇到与nums1里面有的值,则把它放到新建数组中,并删除nums2里对应的值。
    nums2.forEach(n => {//遍历nums2里面的值
        if (map.get(n)) {//如果字典里面有当前这个元素,则
            res.push(n);//放到数组中
            map.delete(n);//立即删除

        }
    });
    return res;
};

7.3 Leetcode:20,有效的括号

在这里插入图片描述

/**

 \* @param {string} s

\* @return {boolean}

 */

var isValid = function (s) {

    // 先判断字符串的长度是否为奇数,为奇数肯定闭合不了
    if (s.length % 2 === 1) {
        return false;
    }
    const stack = [];// 新建一个栈:用数组来模拟这个栈

    const map = new Map();//  新建一个字典

    map.set('(', ')');//把括号的映射关系存到字典里,新建键值对
    map.set('[', ']');
    map.set('{', '}');

    // 扫描字符串:用一个for循环来扫描
    for (let i = 0; i < s.length; i += 1) {//遍历的长度为字符串的长度
        const c = s[i]; // 声明一个变量且把遍历的字符存到这个变量C
        if (map.has(c)) {//判断字典中是否有当前字符
            stack.push(c);//把它推入栈中
        }

        // 如果遇到右括号就看是否与栈顶元素相匹配
        else {
            const t = stack[stack.length - 1];// 先获取栈顶元素stack.length-1数组的最后一位
            if (map.get(t) = c) { //如果当的栈顶元素等于当前元素:map.get(t) = c
                stack.pop(); // 栈里的元素直接出栈
            }
            else {//否则
                return false;
            }
        }
    };

    // 判断栈是否为空stack.length === 0

    return stack.length === 0;

}

7.4 Leetcode:1.两数之和

在这里插入图片描述

解题思路:

  1. 把nums想象成相亲者
  2. 把target 想象成匹配条件
  3. 用字典建立一个婚姻介绍所,存储相亲者的数字和下标。

解题步骤:

  1. 新建一个字典作为婚姻介绍所。
  2. mums 里的值,个来介绍所找对象,没有合适的就先登记着,有合适的就牵手成功。
/**

 \* @param {number[]} nums

\* @param {number} target

 \* @return {number[]}

 */

var twoSum = function (nums, target) {
    const map = new Map();// 新建一个字典作为婚姻介绍所

    // 遍历nums数组,写一个for循环来遍历
    for (let i = 0; i < nums.length; i += 1) {
        const n = nums[i];//通过for循环可以拿到nums的每一个值
        const n2 = target - n;//通过for循环可以拿到每个值想找的对象的数字
        // 问婚姻介绍所有没有我想找的对象
        if (map.has(n2)) {
            return [map.get(n2), i];//获取它对象的下标,以及它自己的下标
        } else {
            map.set(n, i);//没找到对象的要在婚姻介绍所来登记信息
        }
    }
};
 //只有一个for循环:时间复杂度为O(n),新建的一个临时字典 const map = new Map();当它足够大时,也为O(n)

7.5 Leetcode:3.无重复字符的最长子串

在这里插入图片描述

子串与子序列的区别:

  1. 子串必须是母串中连续且无重复字符的字符串。(类似于视频剪辑)
  2. 子序列是有母串的全部字符,但不连续。

解题思路:

  1. 先找出所有的不包含重复字符的子串
  2. 找出长度最大那个子串,返回其长度即可

解题步骤:

  1. 用双指针维护一个滑动窗口,用来剪切子串
  2. 不断移动右指针,遇到重复字符,就把左指针移动到重复字符的下一位
  3. 移动过程中,记录所有窗口的长度,并返回最大值
/**
 \* @param {string} s
 \* @return {number}
 */
var lengthOfLongestSubstring = function (s) {
    //用双指针维护一个滑动窗口
    let l = 0;//左指针的起始位置是 0
    let res = 0;// 记录最大窗口的长度

    const map = new Map();//建立一个字典

    for (let r = 0; r < s.length; r += 1) {//实现了不断移动右指针
        if (map.has(s[r]) && map.get(s[r]) >= l) {//下一次如果发现了这个字符,那么它就是重 复字符
            l = map.get(s[r]) + 1;//把l移到重复字符的下一个字符
        }

        res = Math.max(res, r - l + 1);//新的res, 左指针减右指针加 1
        map.set(s[r], r);  //把当前的值以及它的下标放到字典里面
    }
    return res;
};

 //只有一个for循环:时间复杂度为O(n),有一个字典const map = new Map();所以空间复杂度为O(m),m是字符串中不重复字符的个数

7.6 Leetcode:76.最小覆盖子串

在这里插入图片描述

解题思路:

  1. 先找出所有的包含T的子串。
  2. 找出长度最小的那个子串,返回即可。

解题步骤:

  1. 用双指针维护一个滑动窗口
  2. 移动右指针,找到包含T的子串,移动左指针,尽量减少包含T的子串的长度
  3. 循环上述过程,找出包含T的最小子串
/**

 \* @param {string} s

 \* @param {string} t

\* @return {string}

 */

var minWindow = function (s, t) {

    //用双指针维护一个滑动窗口
    let l = 0;//左指针的起始位置是 0
    let r = 0;//右指针的起始位置是 0

    const need = new Map();//新建一个字典,表示子需要的字符及它个数

    //用for of遍历字典
    for (let c of t) {
        need.set(c, need.has(c) ? need.get(c) + 1 : 1);//每个字符以及它的长度
    }
    let needType = need.size;//需要的类型长度
    let res = '';//新建一个字串

    //移动右指针r+=1
    while (r < s.length) {
        const c = s[r];//获取右指针当前字符
        // 如果右指针的当前字符在需求列表里面
        if (need.has(c)) {
            need.set(c, need.get(c) - 1);//不再需要它了
            if (need.get(c) === 0) {//如果它需要的某个字符的变量=0
                needType -= 1;
            }
        }

        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);
                //更新needType
                if (need.get(c2) === 1) {
                    needType += 1;
                }
            }
            l += 1;
        }

        r += 1;
    }
    return res;

};

7.7 字典总结

  1. 字典:与集合类似,字典也是一种存储唯一值的数据结构,但他是以键值对的形式来存储。
  2. ES6中的字典:Map
  3. 字典的常用操作:键值对的增删改查
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ZGLi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值