JavaScript刷LeetCode拿offer-js版字典

1. 字典简介

  • 与集合类似,字典也是一种存储唯一值的数据结构,但它是以键值对的形式来存储。
  • 使用 ES6 Map

1.1 字典的常用操作

const m = new Map();

// 增
m.set('a', 'aa');
m.set('b', 'bb');

// 删
m.delete('b');
m.clear();

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

// 查
m.get('a');

2. LeetCode: 349. 两个数组的交集

image.png

2.1 解题思路

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

2.2 解题步骤

  • 新建一个字典,遍历nums1,填充字典
  • 遍历nums2, 遇到字典里的值就选出,并从字典中删除。
/** * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]} */
var intersection = function (nums1, nums2) {
    // 集合Set 实现方式
    // return [...new Set(nums1)].filter(item => nums2.includes(item))

    const map = new Map();
    nums1.forEach(n => {
        map.set(n, true)
    })
    const res = [];
    nums2.forEach(n => {
        if (map.get(n)) {
            res.push(n);
            map.delete(n);
        }
    })
    return res
};

3. LeetCode:20. 有效的括号

image.png

/** * @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 (let i = 0; i < s.length; i += 1) {
        const c = s[i];
        if (c === '(' || c === '{' || 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;
};

4. LeetCode: 1. 两数之和

image.png

4.1 解题思路

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
  • 把nums 想象成相亲者
  • 把target 想象成匹配条件
  • 用字典建立一个婚姻介绍所,存储相亲者的数字和下标
  • 参考视频:传送门

4.2 解题步骤

  • 新建一个字典作为婚姻介绍所
  • nums 里的值,逐个来介绍找对象,没有何止的就先登记者,有合适的就牵手
/** * @param {number[]} nums
 * @param {number} target
 * @return {number[]} */
var twoSum = function (nums, target) {
    const map = new Map()
    for (let i = 0; i < nums.length; i += 1) {
        const n = nums[i];
        const n2 = target - n;
        if (map.has(n2)) {
            return [map.get(n2), i]
        } else {
            map.set(n, i)
        }
    }
};

执行用时:56 ms, 在所有 JavaScript 提交中击败了99.77%的用户

内存消耗:39.9 MB, 在所有 JavaScript 提交中击败了37.04%的用户

内存消耗为 O(n), 我们可以通过二分查找,用时间换空间的方式,进行处理

5. LeetCode: 3. 无重复字符的最长子串

5.1 题目描述

image.png

5.2 解题步骤

  • 用双指针维护一个滑动窗口,用来剪切子串
  • 不断移动右指针,遇到重复字符,就把左指针移动到重复字符的下一位。
  • 过程中,记录所有窗口的长度,并返回最大值。

5.3 代码实现

/** * @param {string} s
 * @return {number} */
var lengthOfLongestSubstring = function (s) {
    let l = 0; // 左指针位置
    let res = 0; // 定义返回结果
    const map = new Map();
    for (let r = 0; r < s.length; r += 1) {
        // 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)
    }
    return res;
};
  • 时间复杂度 O(n)
  • 空间复杂度 O(m)

6. LeetCode: 76. 最小覆盖子串

6.1 题目描述

image.png

6.2 解题思路

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

6.3 解题步骤

  • 用双指针维护一个滑动窗口。
  • 移动右指针,找到包含T的子串,移动左指针,尽量减少包含T的子串的长度。

6.3 代码实现

/** * @param {string} s
 * @param {string} t
 * @return {string} */
var minWindow = function (s, t) {
    let l = 0;
    let 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.has(c)) {
            need.set(c, need.get(c) - 1);
            if (need.get(c) === 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)
                if (need.get(c2) === 1) needType += 1;
            }
            l += 1;
        }
        r += 1;
    }
    return res
};
  • 时间复杂度 O(m+n),m 是t的长度,n是s的长度
  • 空间复杂度 O(m)

7. 总结:

  • 与集合类似,字典也是一种存储唯一值的数据结构,但是它以键值对的形式来存储
  • ES6中有字典,名为Map
  • 字典的常用操作:键值对的增删改查

写代码使我快乐

20 声望
1 粉丝
0 条评论
推荐阅读
JavaScript刷LeetCode拿offer-双指针
一、前言  一般情况下,遍历数组(或者字符串)操作,都是采用单指针从前往后或者从后往前依次访问数组(或者字符串)中的元素。  而对于以下情况,只采用单指针处理,则会徒增时间复杂度和空间复杂度:例如:找...

hellocoder2028阅读 60

正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青56阅读 8.5k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy48阅读 7k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木75阅读 7.1k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs42阅读 6.8k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木45阅读 8.5k评论 6

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木35阅读 6.7k评论 10

写代码使我快乐

20 声望
1 粉丝
宣传栏