深入探讨JavaScript中的队列,结合leetcode全面解读

news2024/11/24 18:21:14

前言

队列作为一种基本的数据结构,为解决许多实际问题提供了有效的组织和处理方式,对于提高系统的稳定性、可靠性和效率具有重要作用,所以理解队列是很重要的。

本文深入探讨JavaScript中的队列这种数据结构,结合leetcode题目讲解

题目直达:

232. 用栈实现队列 - 力扣(LeetCode)

239. 滑动窗口最大值 - 力扣(LeetCode)

什么是队列

队列是一种特殊的线性表数据结构,它遵循“先进先出”(First-In-First-Out,FIFO)的原则

即先进入队列的元素先出队列,进去是abc的顺序,出来也是abc的顺序

image.png

JavaScript实现队列

JavaScript 中,没有专门的一个关键词来直接表示队列。

可以使用数组的方法来模拟队列的行为。

常见的实现方式

  • 数组的 push() 方法在队尾添加元素,使用 shift() 方法在队首移除元素

  • 数组的 pop()在队尾删除元素、unshift()方法在队添加元素

既然我们明白了这个点,我们就知道了,如果要从队列里面拿数据就一定会造成队列长度发生变化

所以队列的遍历不能用for循环,队列的长度是动态变化的

分析一下下面的代码

const queue = []

queue.push('a')
queue.push('b')
queue.push('c')


for (let i = 0; i < queue.length; i++) {
    const top = queue.shift()
    console.log(top);
}

这段代码的执行结果为

image.png

这并不是我们想要的结果,这就是因为在循环中使用 shift 方法会导致每次循环时队列的长度发生变化,从而导致循环次数不正确

我们可以使用两种方式去遍历

  • 使用一个临时变量来保存队列的初始长度,然后基于这个长度进行循环操作
const queue = [];

queue.push('a');
queue.push('b');
queue.push('c');

const length = queue.length;
for (let i = 0; i < length; i++) {
  const top = queue.shift();
  console.log(top);
}
  • 使用while循环去遍历,只要队列的长度大于 0,就会不断从队列中取出元素并打印
const queue = [];

queue.push('a');
queue.push('b');
queue.push('c');

while (queue.length > 0) {
  const top = queue.shift();
  console.log(top);
}

232. 用栈实现队列 - 力扣(LeetCode)

题目直达232. 用栈实现队列 - 力扣(LeetCode)

接下来我们用232题来讲解一下栈数据结构,首先分析题目

image.png

题目要求我们去打造一个栈结构,并且实现一系列的方法

既然是使用两个栈去实现,首先我们肯定是需要去准备两个栈

var MyQueue = function () {
    this.stack1 = []
    this.stack2 = []
};

接下来我们考虑如何通过这两个栈去实现队列效果呢?

动画.gif

从这个动画我们 可以看到,我们首先去存入到stack1,然后再存入stack2,这样就实现了翻转,就能够实现先进先出的效果了

接下来我们就编写代码

var MyQueue = function () {
    this.stack1 = []
    this.stack2 = []
};

MyQueue.prototype.push = function (x) {
    this.stack1.push(x)
};


MyQueue.prototype.pop = function () {
    if (this.stack2.length === 0) {
        while (this.stack1.length) {
            this.stack2.push(this.stack1.pop())
        }
    }
    return this.stack2.pop()
};

MyQueue.prototype.peek = function () {
    if (this.stack2.length === 0) {
        while (this.stack1.length) {
            this.stack2.push(this.stack1.pop())
        }
    }
    return this.stack2[this.stack2.length - 1]
};

MyQueue.prototype.empty = function () {
    return this.stack1.length === 0 && this.stack2.length === 0
};
  1. MyQueue 类的构造函数:

    • 初始化了两个空数组 stack1stack2,用于模拟队列的操作。
  2. push 方法:

    • 接收一个参数 x,将其直接压入 stack1 。这相当于向队列的尾部添加元素。
  3. pop 方法:

    • 首先检查 stack2 是否为空。
    • 如果为空,通过一个 while 循环,将 stack1 中的元素逐个弹出并压入 stack2 。这样就实现了将 stack1 中的元素顺序反转,从而模拟出队列的出队操作。
    • 最后,从 stack2 中弹出并返回顶部元素。
  4. peek 方法:

    • pop 方法类似,先检查 stack2 是否为空,如果为空则进行元素转移。
    • 然后返回 stack2 的最后一个元素,但不将其弹出,实现了查看队列头部元素的功能。
  5. empty 方法:

    • 检查 stack1stack2 的长度是否都为 0,如果都是 0 则表示队列为空,返回 true;否则返回 false

239. 滑动窗口最大值 - 力扣(LeetCode)

题目直达239. 滑动窗口最大值 - 力扣(LeetCode)

image.png

var maxSlidingWindow = function (nums, k) {
    var a = 0;
    var b = k - 1;
    var arr = []
    while (b < nums.length) {
        var max = -Infinity
        for (var i = a; i <= b; i++) {
            if (max < nums[i])
                max = nums[i];
        }
        arr.push(max)
        a++
        b++
    }
    return arr;
};



var maxSlidingWindow = function (nums, k) {
    const len = nums.length
    const res = []
    const queue = []//维护一个递减队列
    for (let i = 0; i < length; i++) {
        while (queue.length && nums[i] > queue[queue.length - 1]) {
            queue.pop()
        }
        queue.push(nums[i])
        while (queue.length && queue[0] <= i - k) {
            queue.shift()
        }

        if (i >= k - 1) {
            arr.push(nums[queue[0]])
        }
    }
    return res
}

第一段代码:

  • 它使用了两个指针 ab 来表示滑动窗口的起始和结束位置。
  • 在每次滑动窗口中,通过一个内层的循环遍历窗口内的所有元素来找到最大值,并将其添加到结果数组 arr 中。
  • 这种方法的时间复杂度较高,因为对于每个窗口都需要进行一次遍历查找最大值。

第二段代码:

  • 它使用一个单调递减的队列 queue 来维护滑动窗口内可能成为最大值的元素。
  • 当新元素大于队列末尾的元素时,将末尾元素弹出,以保持队列的递减性质。
  • 当队列头部的元素不在当前窗口范围内时,将其移出队列。
  • 当窗口滑动到足够长度后,将队列头部的元素作为当前窗口的最大值添加到结果数组 res 中。

总结

本文介绍了JavaScript中的队列,结合leetcode全面解读

希望看到这里的你能够有所收获!!!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1893041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端笔记-day12

文章目录 01-视口02-宽度适配方案03-rem体验04-rem基本使用05-媒体查询06-rem适配07-rem布局08-less-体验09-less-注释10-less-运算11-less-嵌套12-less-变量13-less-导入14-less-导出15-less-禁止导出16-急速问诊&#xff08;不准确写法&#xff09;index.htmlindex.css 17-急…

新章节:全设备通用调度算法-通讯重构

新章节&#xff1a;全设备通用调度算法-通讯重构 文章目录 新章节&#xff1a;全设备通用调度算法-通讯重构前言一、重构了TCP和UDP通讯二、优化了OPC和OPCUA三、升级了监控客户端四、升级了通讯的图形化其他升级 前言 现在真的很懒也很少写代码了&#xff0c;写代码和更新进度…

Laravel5+mycat 报错 “Packets out of order”

背景 近期对负责项目&#xff0c;配置了一套 主从复制的 MySQL 集群 使用了中间件 mycat 但测试发现&#xff0c;替换了原来的数据连接后&#xff0c;会出现 Packets out of order 的报错 同时注意到&#xff0c;有的框架代码中竟然也会失效&#xff0c;比如 controller 类中&…

智慧园区可视化:构建全方位智能管理体系

通过图扑的 2D、 3D 和 GIS 可视化技术结合倾斜摄影、数字孪生和视频融合等技术&#xff0c;将园区各类数据集成展示&#xff0c;实时监控和分析环境与设施状况&#xff0c;提升管理效能和安全水平&#xff0c;实现智慧园区的全方位智能化运营。

vscode python调试,找不到控制调试工具栏,被隐藏了

问题&#xff1a; 如图所示&#xff0c;最开始蓝框中的调试台被莫名其妙的隐藏了&#xff0c;没法进行调试。 解决办法&#xff1a; 打开设置输入调试点击调试&#xff08;31&#xff09;找到红框选的那个选项&#xff0c;选择floating

多步预测模型大更新

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;Transformer-BiGRU预测模型-CSDN博客 独家原创 | 基于TCN-SENet BiGRU-GlobalAttention并行预测模型-CSDN博客 独家原创 | B…

正交的拉丁方阵(MOLS)

在组合数学中&#xff0c;如果两个同阶的拉丁方阵叠加后&#xff0c;每个位置上的有序对条目都是唯一的&#xff0c;则这两个拉丁方阵被称为正交的。 如果一组同阶的拉丁方阵中&#xff0c;任意两个方阵都是正交的&#xff0c;则这组方阵被称为一组相互正交的拉丁方阵&#xf…

SSM高校学生综合测评系统-计算机毕业设计源码16154

摘要 随着互联网时代的到来,同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个BS 结构的高校学生综合测评系统,会使高校学生综合测评系统工作系统化、规范化,也会提高高校学生综合测评系统平台形象,提高管理效率。 本学生综合测评系统是针对目前高校学生…

.Net C#执行JavaScript脚本

文章目录 前言一、安装二、执行 JavaScript 脚本三、与脚本交互四、JS 调用 C# 方法五、多线程使用总结 前言 ClearScript 是一个 .NET 平台下的开源库&#xff0c;用于在 C# 和其他 .NET 语言中执行脚本代码。它提供了一种方便和安全的方法来将脚本与应用程序集成&#xff0c;…

CVE-2024-6387 分析

文章目录 1. 漏洞成因2. 漏洞利用前置知识2.1 相关 SSH 协议报文格式2.2 Glibc 内存分配相关规则 3. POC3.1 堆内存布局3.2 服务端解析数据时间测量3.3 条件竞争3.4 FSOP 4. 相关挑战 原文链接&#xff1a;个人博客 近几天&#xff0c;OpenSSH爆出了一个非常严重的安全漏洞&am…

软件开发中常用的11款bug记录、跟踪、管理系统对比【2024更新】

软件开发项目的复杂性不断增加&#xff0c;有效的bug管理变得尤为关键。对开发团队而言&#xff0c;没有什么比选择一款合适的Bug跟踪工具更重要的了。工具的功能、界面友好度、整合能力及成本都是决策的关键因素。 1、PingCode 推荐指数&#xff1a;五星 简介&#xff1a;P…

常微分方程算法之编程示例十一-两点狄利克雷边值问题(紧差分法)

目录 一、研究问题 二、C++代码 三、计算结果 一、研究问题 本节我们采用紧差分法对示例八中的两点狄利克雷边值问题进行外推求解,相应的原理及推导思路请参考: 常微分方程算法之高精度算法(Richardson法+紧差分法)_richardson外推法-CSDN博客https://blog.csdn.net/L_…

python gdal 压缩栅格数据

1 压缩方法LZW 使用 LZW&#xff08;Lempel-Ziv-Welch&#xff09;&#xff0c;主要对图像数据压缩&#xff0c;可逆 2 代码 函数gdal_translate()&#xff1a;转换栅格的不同格式 我们使用的数据是GTiff格式的数据 GTiff – GeoTIFF File Format — GDAL documentation 参…

秒拿AI模型API Key!Chat2DB AI模型切换实用秘籍

智谱AI&#xff08;ZhiPu AI&#xff09; 智谱 AI 是由清华大学计算机系技术成果转化而来的公司&#xff0c;致力于打造新一代认知智能通用模型。 1.申请调用权限 智谱AI开放平台网址&#xff1a;https://open.bigmodel.cn/ 点击开始使用&#xff0c;进行登录/注册。 智谱A…

I方C是什么啊,老是听到他们说

首先说一下串口通讯&#xff0c;只能在两个设备之间进行&#xff0c;如下图&#xff1a; 若三个设备相互通讯&#xff0c;则每个设备需要两组串口。它们其实是三组相互独立的串口通讯。如下图&#xff1a; 若是四个设备相互通讯就更麻烦了&#xff0c;以此类推。这样一来&#…

【CUDA】 矩阵乘向量 matVecMul

Matrix - Vector Multiplication 矩阵-向量乘法是线性代数中的基本操作。它用于将一个矩阵与一个向量相乘。乘法的结果是与输入向量大小相同的向量。 矩阵和向量的乘法如图1所示。 图1 基础kernel与共享内存kernel 执行矩阵-向量乘法的基础kernel是使用单个线程执行输出向量…

教育行业的网络安全:保护学生数据与防范网络欺凌

在数字化的春风中&#xff0c;教育行业迎来了知识的繁花似锦&#xff0c;然而&#xff0c;随之而来的网络安全风暴也悄然逼近。学生数据的脆弱性与网络欺凌的阴影交织成一幅复杂的画卷&#xff0c;呼唤着教育工作者与技术专家共同编织一张密不透风的网络安全之网。本文深入探讨…

深度之眼(二十九)——神经网络基础知识(四)-循环神经网络

文章目录 一、 学习目标二、序列数据三、语言模型四、循环神经网络4.1 RNN的反向传播 五、门控循环单元-GNU5.1 候选隐藏状态 六、长短期记忆网络-LSTM七、回顾 一、 学习目标 二、序列数据 序列数据是常见的数据类型&#xff0c;前后数据通常具有关联性 三、语言模型 综合…

前后端分离:四种开发模式与实践指南

前后端分离&#xff1a;四种开发模式与实践指南 什么是前后端分离 当业务变得越来越复杂或产品线越来越多时&#xff0c;原有的开发模式就无法满足业务需求了。 产品越来越多&#xff0c;展现层的变化越来越快、越来越多&#xff0c;此时应该进行前后端分离的分层抽象&#…