当前位置: 首页 > news >正文

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

前言

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

本文深入探讨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 = -Infinityfor (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.lengthconst 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全面解读

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

相关文章:

  • nvm安装以及idea下vue启动项目过程和注意事项
  • 华为仓颉编程语言
  • SOLID:软件系统设计的五个基本原则
  • [笔记] 高等数学在各工程门类的典型应用场景
  • adb push 报错 ...error: failed to copy...
  • 数据识别概述
  • Linux多进程和多线程(一)-进程的概念和创建
  • CSS Border(边框)
  • IO多路复用学习
  • c++习题09-分离整数的各个数
  • Python特征工程 — 1.3 对数与指数变换
  • 检测水管缺水的好帮手-管道光电液位传感器
  • 最新mysql打开远程访问和修改最大连接数
  • Python爬取国家医保平台公开数据
  • jsqlparse工具拦截sql处理和拓展
  • (三)从jvm层面了解线程的启动和停止
  • @jsonView过滤属性
  • 4. 路由到控制器 - Laravel从零开始教程
  • Angularjs之国际化
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Docker 笔记(2):Dockerfile
  • Gradle 5.0 正式版发布
  • HTTP 简介
  • JavaScript服务器推送技术之 WebSocket
  • Java比较器对数组,集合排序
  • JS字符串转数字方法总结
  • Leetcode 27 Remove Element
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Windows Containers 大冒险: 容器网络
  • 百度小程序遇到的问题
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 如何学习JavaEE,项目又该如何做?
  • 移动端 h5开发相关内容总结(三)
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #laravel 通过手动安装依赖PHPExcel#
  • #vue3 实现前端下载excel文件模板功能
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • $().each和$.each的区别
  • (C语言)fgets与fputs函数详解
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)shell调试方法
  • ./configure,make,make install的作用(转)
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .NET命名规范和开发约定
  • [BUUCTF 2018]Online Tool(特详解)