【LeetCode】升级打怪之路 Day 12:单调队列

今日题目:

  • 239. 滑动窗口最大值 | LeetCode

今天学习了单调队列这种特殊的数据结构,思路很新颖,值得学习。

Problem:单调队列 【必会】

与单调栈类似,单调队列也是一种特殊的数据结构,它相比与普通的 queue,增加了一个新的接口 max() 来获取当前队列的最大值

新增的 max() 是我们选用这个数据结构的最重要原因,单调队列不仅仅可以通过 offer()poll() 接口来实现 FIFO 的元素进出顺序,还额外增加了 max() 接口让我们获取到当前队列中的最大元素。

单调队列主要用来解决下面这个场景:我们会时刻向一个集合中增加新元素或减少旧元素,同时每次可以获取到当前这个集合中的最大值。优先级队列也可以满足这个需求,但优先级队列无法满足 FIFO 的元素进出顺序,这也是必须使用单调队列的原因。

假如有一个数组 window,并知道它的最大值是 A,此时向 window 增加一个新元素 B,我们只需要比较 A 和 B 就可以得到当前 window 中的最大值;但如果删除一个旧元素 C,就麻烦了,因为如果这个删除的 C 恰恰就是最大值 A,那么最大值就要重新遍历 window 来寻找了,从而导致复杂度飙升。这就是单调队列所需要解决的难题。

下面看一下单调队列的经典应用:滑动窗口最大值

LC 239. 滑动窗口最大值 【classic】 ⭐⭐⭐⭐⭐

239. 滑动窗口最大值 | LeetCode

如果我们能够实现数据结构“单调队列” MonoQueue,那我们就每次向右滑动我们的窗口时,向 monoQueue 中新增一个窗口右边的新元素,移除一个窗口左边的旧元素,然后调用 max() 接口获取当前窗口的最大值,就可以计算出题目所需要的最终结果。

在这里插入图片描述

所以重点在于如何实现 MonoQueue。

我们需求的关键是:需要能够快速得知当前队列中的最大值。由于窗口滑动时是有顺序的,先进入的元素一定会先出去,所以如果新进入的一个元素,那么比它老的还比它小的那些元素就永远不可能成为当前队列中的最大值了,因为老元素一定会比新元素更早地离开队列。所以,每次在入队一个新元素时,就可以把队列中比他小的元素都抛弃掉了

在这里插入图片描述
如上图,当元素 5 进入队列后,就可以一下子把 4、3、2、1 全给抛弃掉了,因为这些旧元素在队列的时候 5 一定在,所以这些旧元素一定成不了“当前队列的最大值”。

根据以上分析,单调队列 MonoQueue 的实现如下:

class MonoQueue {private Deque<Integer> maxQ = new LinkedList<>();public void offer(int num) {// 将小于 num 的元素全部删除while (!maxQ.isEmpty() && maxQ.getLast() < num) {maxQ.removeLast();}// 将 num 加入队尾maxQ.addLast(num);}public int max() {return maxQ.getFirst();  // 单调队列,队首就是最大元素}public void poll(int n) {if (maxQ.getFirst() == n) {  // 判断需要移除的是否是队首,如果不是的话,就是比队首小还比队首老的元素,已经被移除了,那就啥也不用干maxQ.removeFirst();}}
}

这里有两个易错点:

  • offer() 函数实现中,第一步删掉掉小于 num 的元素,但注意别把等于它的元素删除了,因为如果把相等的元素也删掉的话,实现 poll() 接口时,就不太好判断 队首最大元素 是否就是我们当前需要 poll 的元素了(我们是通过值相等来判断的)
  • 在实现 poll() 函数时,其参数 n 表示期待删除的元素,因为我们这个 MonoQueue 并没有保留全部入队元素,所以当需要删除一个已经被删除的元素时,poll() 接口只需要立刻返回就可以了。

在实现了 MonoQueue 后,我们解决这个问题就容易多了:

    public int[] maxSlidingWindow(int[] nums, int k) {MonoQueue monoQueue = new MonoQueue();List<Integer> result = new ArrayList<>();// 将前 k-1 个元素填充到队列中for (int i = 0; i < k - 1; i++) {monoQueue.offer(nums[i]);}for (int i = k - 1; i < nums.length; i++) {// 加入窗口右边的新元素monoQueue.offer(nums[i]);// 获取窗口内最大元素,并加入到结果集中result.add(monoQueue.max());// 移除窗口左边的旧元素monoQueue.poll(nums[i - k + 1]);}return result.stream().mapToInt(Integer::valueOf).toArray();}

通过这个题,我们可以更加深入地理解单调队列的具体用法。在有些情况下,我们除了在 MonoQueue 里面维护一个 maxQ 之外,还可以额外维护一个标准的 queue,从而对外表现出正常的 offer() 和 poll() 接口。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux入门到入土

Linxu Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX&#xff08;可移植操作系统接口&#xff09…

Onenote软件新建笔记本时报错:无法在以下位置新建笔记本

报错现象&#xff1a; 当在OneNote软件上&#xff0c;新建笔记本时&#xff1a; 然后&#xff0c;尝试重新登录微软账户&#xff0c;也不行&#xff0c;提示报错&#xff1a; 解决办法&#xff1a; 打开一个新的记事本&#xff0c;复制粘贴以下内容&#xff1a; C:\Users\Adm…

Windows上构建一个和Linux类似的Terminal

感谢大佬批评指正&#xff0c;现已更新 preview Target&#xff1a;致力打造最赏心悦目Window下的终端&#xff0c;同时能够很接近Linux的使用习惯 key word&#xff1a;windows终端美化 windows terminal windows powershell 类似Linux下的Window终端 Window也能用ll windows…

本地如何配置支付宝模拟支付场景并结合内网穿透实现公网环境调试开发?

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候&#xff0c;往往沙箱环境部署在本地&#xff0c;局限性大&#xff0c;在沙箱环境…

【java】final、finally和finalize的区别

例题&#xff1a; package com.overload;public class ExceptionTest {public static void main(String[] args) {int result test();System.out.println(result); //100}public static int test(){int i 100;try {return i;} finally {i;}} }结果为&#xff1a;100 造成结果…

计算机专业大学四年应该如何规划(Java方向)

计算机专业的学生&#xff0c;如何在大学四年内提高自己的竞争力&#xff0c;毕业之后直接进大厂工作&#xff1f; 以下将从大学四年计算机专业的学习规划、课程设置、能力提升、参考书籍等方面&#xff0c;为同学们提供一些建议和指导。 大一&#xff1a; 主攻技能学习并且达…

lv20 QT事件5

1 事件模型 2 事件处理 virtual void keyPressEvent(QKeyEvent *event) virtual void keyReleaseEvent(QKeyEvent *event) virtual void mouseDoubleClickEvent(QMouseEvent *event) virtual void mouseMoveEvent(QMouseEvent *event) virtual void mousePressEvent(QMou…

NACOS在Windows和Linux下的安装教程

目录 1、Windows安装 1.1、下载安装包 1.2、解压 1.3、端口配置 1.4、启动 1.5、访问 2、Linux安装 2.1、安装JDK 2.2、上传安装包 2.3、解压 2.4、端口配置 2.5、启动 3、Nacos的依赖 1、Windows安装 开发阶段采用单机安装即可。 1.1、下载安装包 在Nacos的Git…

C++ sort排序

sort函数接受两个迭代器作为参数&#xff0c;分别表示要排序的范围的起始和结束位置。 请注意&#xff0c;sort函数默认使用小于运算符&#xff08;<&#xff09;来比较元素的顺序&#xff0c;默认从小到大排。 在这里&#xff0c;使用str.begin()和str.end()来表示整个字符…

水豚鼠标助手 强大的鼠标美化工具

水豚鼠标助手 水豚鼠标助手是一款 鼠标换肤、屏幕画笔、放大镜、聚光灯、屏幕放大、倒计时功能的强大屏幕演示工具。 软件助手获取 水豚鼠标助手1.0.0 安装教程 第一步&#xff1a;下载后&#xff0c;双击软件安装包 第二步&#xff1a;Windows可能会出现提示弹窗&#xff…

前端同时传递文件数据+非文件数据,前后端解决方案

之前录制视频《文件上传组件》的时候有位观众提了个问题&#xff0c;如果我没有理解错的话&#xff0c;应该就是前后同时传递文件数据 非文件数据&#xff0c;前后端数据该如何接收&#xff0c;这里我给出我自己的解决方案 tip:下文在编写前端代码的时候&#xff0c;用到了这篇…

【C++练级之路】【Lv.10】【STL】priority_queue类和反向迭代器的模拟实现

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 一、仿函数1.1 仿函数的介绍1.2 仿函数的优势 二、priority_queue2.1 push2.2 pop2.3 top2.4 size2.5 empty 三、…

ChatGPT数据分析应用——同期群分析

ChatGPT数据分析应用——同期群分析 ​ 同期群分析在一定程度上属于分组分析的一个变种。顾名思义&#xff0c;同期群就是相同时期的群体&#xff0c;同期群分析就是针对相同时期的群体展开分析。接下来我们让ChatGPT解释这个方法的概念并提供相应的案例。发送如下内容给ChatG…

1.2 在卷积神经网络中,如何计算各层感受野的大小

1.2 在卷积神经网络中&#xff0c;如何计算各层感受野的大小 分析与解答&#xff1a; 在卷积神经网络中&#xff0c;由于卷积的局部连接性&#xff0c;输出特征图上的每个节点的取值&#xff0c;是由卷积核在输入特征图对应位置的局部区域内进行卷积而得到的&#xff0c;因此这…

程序环境和预处理(2)

文章目录 3.2.7 命名约定 3.3 #undef3.4 命令行定义3.5 条件编译3.6 文件包含3.6.1 头文件被包含的方式3.6.2 嵌套文件包含 4. 其他预处理指令 3.2.7 命名约定 一般来讲函数和宏的使用语法很相似&#xff0c;所以语言本身没法帮我们区分二者&#xff0c;那我们平时的一个习惯是…

Flutter开发进阶之Flutter Web加载速度优化

Flutter开发进阶之Flutter Web加载速度优化 通常使用Flutter开发的web加载速度会比较慢&#xff0c;原因是Flutter web需要加载的资源处于国外&#xff0c;以下是据此所做的相应优化。 一、FlutterWeb打包 flutter build web --web-renderer canvaskit使用新命令打包 flut…

微信小程序构建npm失败解决方式

安装完所需要的依赖后&#xff0c;在微信开发者工具菜单栏中选择&#xff1a;“工具” -> “构建 npm”&#xff0c;但是失败。 解决方法&#xff1a;修改 project.config.json 开发者工具创建的项目&#xff0c;miniprogramRoot 默认为 miniprogram&#xff0c;package.js…

大数据可视化python01

import pandas as pd import matplotlib.pyplot as plt# 设置中文改写字体 plt.rcParams[font.sans-serif] [SimHei]# 读取数据 data pd.read_csv(C:/Users/wzf/Desktop/读取数据进行数据可视化练习/实训作业练习/瓜果类单位面积产量.csv ,encoding utf-8)#输出 print(data)…

数字孪生与智慧交通的融合发展:推动交通行业数字化转型,构建智慧城市新生态

随着信息技术的快速发展和城市化进程的深入推进&#xff0c;交通行业正面临着前所未有的机遇与挑战。传统的交通管理模式已难以满足日益增长的交通需求&#xff0c;而数字化转型则成为了推动交通行业创新发展的必由之路。数字孪生技术作为一种前沿的信息技术手段&#xff0c;为…

【XR806开发板试用】SPI外设使用驱动OLED显示

XR806 SPI SPI功能引脚 阅读芯片功能引脚相关资料&#xff0c;使用硬件SPI。 https://xr806.docs.aw-ol.com/study/hard_pin/ 阅读SDK SPI使用例程在xr806\device\xradio\xr806\xr_skylark\project\example\spi 路径下 SPI自发自收测试 准备 短接开发板上的MOSI(PB04)和…