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

【数据结构-队列 二】【单调队列】滑动窗口最大值

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【单调队列】,使用【队列】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

滑动窗口最大值【HARD】

还是一道经典应用题

题干

在这里插入图片描述

解题思路

对于每个滑动窗口,我们可以使用 O(k)的时间遍历其中的每一个元素,找出其中的最大值。对于长度为 n的数组nums 而言,窗口的数量为 n−k+1,因此该算法的时间复杂度为 O((n−k+1)k)=O(nk),会超出时间限制,因此我们需要进行一些优化。我们可以想到,对于两个相邻(只差了一个位置)的滑动窗口,它们共用着 k−1 个元素,而只有 1 个元素是变化的。我们可以根据这个特点进行优化

  • 在上述滑动窗口形成及移动的过程中,我们注意到元素是从窗口的右侧进入的,然后由于窗口大小是固定的,因此多余的元素是从窗口左侧移除的。 一端进入,另一端移除,这不就是队列的性质吗?所以,该题目可以借助队列来求解

  • 设置双端队列为单调递减队列

  • 当窗口未形成时,每次拿新的元素与队尾元素比较,如果大于队尾元素,则原队尾元素从尾部出队

  • 当窗口形成时,队首元素就是最大元素,将其从队列头部出队,并加入结果集

  • 当窗口形成后并继续滑动时,队首元素也要从队列头部出队,下一个最大值结果将出现在下一个滑动窗口中

该题目的求解思路就清晰了,具体如下:

  1. 遍历给定数组中的元素,如果队列不为空且当前考察元素大于等于队尾元素,则将队尾元素移除。直到,队列为空或当前考察元素小于新的队尾元素
  2. 由于数组下标从0开始,因此当窗口右边界right+1大于等于窗口大小k时,意味着窗口形成。此时,队首元素就是该窗口内的最大值。
  3. 队首元素的下标小于滑动窗口左侧边界left时,表示队首元素已经不再滑动窗口内,因此将其从队首移除。

由此思路可以写代码了

代码实现

给出代码实现基本档案

基本数据结构数组
辅助数据结构单调队列
算法
技巧双指针、滑动窗口

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param num int整型一维数组* @param size int整型* @return int整型ArrayList*/public ArrayList<Integer> maxInWindows (int[] num, int size) {// 1 如果数组为空或者size小于1则返回空集合if (num.length < 1 || size < 1) {return new ArrayList<Integer>();}// 2 定义结果集并及双端单调队列,双端队列存储元素下标ArrayList<Integer> result = new ArrayList<Integer>();LinkedList<Integer> singleQueue = new  LinkedList<Integer>();// 3 开启窗口滑动for (int right = 0; right < num.length; right++) {// 3-1 如果单调队列不为空且队尾元素小于当前值,则出队while (!singleQueue.isEmpty() && num[singleQueue.peekLast()] <= num[right]) {singleQueue.pollLast();}// 当前元素下标入队singleQueue.offerLast(right);// 3-2 计算队首元素左边界,因为窗口固定大小,所以right向右移动时,left也向右移动int left = right - size + 1;if (left > singleQueue.peekFirst()) {// 如果当前队列中最大值的索引已不在窗口中,则弹出队列singleQueue.pollFirst();}// 3-3 如果right + 1 >= size,则意味着窗口形成,则队首元素即为窗口最大值,首次窗口形成后此判断条件一直成立if (right + 1 >= size) {result.add(num[singleQueue.peekFirst()]);}}return result;}
}

因为单调队列不限制大小,所以每次获取最大值前要先进行判断,当前队首元素还在不在窗口内,不在窗口内要移出去,防止用例过不去
在这里插入图片描述

复杂度分析

时间复杂度:
空间复杂度:

拓展知识:普通队列、单调队列、优先队列、双向队列

普通队列、单调队列、优先队列和双向队列都是队列数据结构,但它们在性质和用途上有一些区别:

  1. 普通队列(Normal Queue)

    • 普通队列是一种基本的队列数据结构,按照先进先出(FIFO)的原则工作。这意味着最早进入队列的元素最早被移出队列。
    • 普通队列通常用于广泛的应用,例如任务调度、BFS(广度优先搜索)算法等,其中重要的是按照元素的到达顺序进行处理。
  2. 单调队列(Monotonic Queue)

    • 单调队列是一种特殊类型的队列,它通常用于维护队列中元素的单调性,可以是单调递增或单调递减。这意味着元素按照一定的顺序排列。
    • 单调队列通常用于解决一些需要寻找局部最大或最小值的问题,例如在滑动窗口问题中,找到滑动窗口中的最大值或最小值。
    • 单调队列可以通过维护单调性,提高一些特定问题的求解效率。
  3. 优先队列(Priority Queue)

    • 优先队列是一种队列数据结构,它根据元素的优先级(或权重)来确定元素的顺序。具有较高优先级的元素在队列中排在前面。
    • 优先队列通常用于解决需要按照优先级处理任务的问题,例如Dijkstra算法、最小堆和最大堆等数据结构都可以用来实现优先队列。
  4. 双向队列(Double-Ended Queue,Deque)

    • 双向队列是一种允许在队列两端进行插入和删除操作的数据结构,可以在队头和队尾同时进行入队和出队操作。
    • 双向队列通常用于一些需要在队列两端进行高效操作的场景,例如实现队列、栈、滑动窗口等。

总结:

  • 普通队列按照FIFO原则工作,适用于广泛的应用。
  • 单调队列用于维护队列中元素的单调性,以解决一些特定问题。
  • 优先队列用于按照元素的优先级来处理任务或元素,适用于需要根据权重或优先级来排序的场景。
  • 双向队列允许在队列两端进行高效的插入和删除操作,适用于需要在队头和队尾同时操作的场景

相关文章:

【数据结构-队列 二】【单调队列】滑动窗口最大值

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【单调队列】&#xff0c;使用【队列】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…...

如何设置CentOS系统以禁用不必要的网络端口和服务?

要禁用CentOS系统中的不必要的网络端口和服务&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 查看当前正在运行的服务和端口&#xff1a;使用以下命令可以查看正在运行的服务和对应的端口号。 sudo netstat -tuln 2. 停用不必要的服务&#xff1a;根据netstat命令的输…...

【IDEA项目个别类爆红,但是项目可以正常运行】

打开项目时发现idea个别类爆红,但是项目可以正常运行 问题原因&#xff1a;Idea本身的问题&#xff0c;可能是其缓存问题&#xff0c;导致爆红 解决方案&#xff1a;重置Idea 很多时候排查不出代码问题&#xff0c;就尝试一下此操作。 选择目录&#xff1a;File–>Invalida…...

hive 之select 中文乱码

此处的中文乱码和mysql的库表 编码 latin utf 无关。 直接上案例。 有时候我们需要自定义一列&#xff0c;有时是汉字有时是字母&#xff0c;结果遇到这种情况了。 说实话看到这真是糟心。这谁受得了。 单独select 没有任何问题。 这是怎么回事呢&#xff1f; 经过一番检查&…...

优化|优化处理可再生希尔伯特核空间的非参数回归中的协变量偏移

原文&#xff1a;Optimally tackling covariate shift in RKHS-based nonparametric regression. The Annals of Statistics, 51(2), pp.738-761, 2023.​ 原文作者&#xff1a;Cong Ma, Reese Pathak, Martin J. Wainwright​ 论文解读者&#xff1a;赵进 编者按&#xff1a; …...

Netty深入浅出Java网络编程学习笔记(一) Netty入门篇

目录 一、概述 1、什么是Netty 2、Netty的优势 二、入门案例 1、服务器端代码 2、客户端代码 3、运行流程 组件解释 三、组件 1、EventLoop 处理普通与定时任务 关闭 EventLoopGroup 处理IO任务 服务器代码 客户端代码 分工细化 划分Boss 和Work 增加自定义EventLoopGroup 切换…...

自动化产线集控系统(西门子CNC 840D/840DSL远程控制)

1.1项目背景 RQQ/VF120机组目前为1人操作3台机床&#xff0c;需在机台旁监控。为了改善人员在班中劳动强度非常大的现状&#xff0c;调整好每台机床的节奏&#xff0c;以保证机床的最少的等待时间。本项目旨在通过远程监视设备运行过程关键参数&#xff0c;操作人员人员可远程监…...

MVVM 与 MVC区别和应用场景?

MVVM 和 MVC 1. MVC2. MVVM 1. MVC MVC 是 Model View Controller 的缩写 Model&#xff1a;模型层&#xff0c;是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。View&#xff1a;视图层&#xff0c;用户界面渲染逻辑&#xff0c;通常视图…...

Linux开发-Ubuntu软件源工具

开发&验证环境&#xff1a; 操作系统&#xff1a;ubuntu 20.04 软件源&#xff1a;http://archive.ubuntu.com/ubuntu 开发工具 sudo apt install vim sudo apt install git# gnu工具链 sudo apt install gcc sudo apt install g sudo apt install gdb# llvm工具链 sudo …...

环境下载地址

1. DOTNET环境下载 适用于 Visual Studio 的 .NET SDK 下载 (microsoft.com)https://dotnet.microsoft.com/zh-cn/download/visual-studio-sdks...

E. Block Sequence-Codeforces Round 903 (Div. 3)

E. Block Sequence dp题,设dp[i]表示i~n之间的数&#xff0c;需要最小删除数量 那么每一位数有两种情况&#xff0c;设数a[i]&#xff1a; 1.被删除&#xff1a;dp[i]dp[i1]1,这一位等于上一位的加一。 2.被保留&#xff1a;dp[i]min(dp[i],dp[ia[i]1]); #include<iostream…...

路由router

什么是路由? 一个路由就是一组映射关系&#xff08;key - value&#xff09;key 为路径&#xff0c;value 可能是 function 或 component 2、安装\引入\基础使用 只有vue-router3&#xff0c;才能应用于vue2&#xff1b;vue-router4可以应用于vue3中 这里我们安装vue-router3…...

学习编程-先改变心态

编程失败的天才 林一和我很久以前就认识了——我从五年级就认识他了。他是班上最聪明的孩子。如果每个人在家庭作业或考试准备方面需要帮助&#xff0c;他们都会去那里。 有趣的是&#xff0c;林一不是那种连续学习几个小时的孩子。 他的聪明才智似乎与生俱来&#xff0c;几乎毫…...

【Node.js】http 模块

1. http 模块 import http from http // 创建本地服务器接收数据 const server http.createServer((req, res) > {console.log(req.url)res.writeHead(200, { Content-Type: application/json // Content-Type: text/html;charsetutf-8 // 将内容以 html 标签和 utf-8 的…...

S/4 HANA 大白话 - 财务会计-2 总账主数据

接下来看看财务模块的一些具体操作。 总账相关主数据 公司每天运转&#xff0c;每天办公室有租金&#xff0c;有水电费&#xff0c;有桌椅板凳损坏&#xff0c;鼠标损坏要换&#xff0c;有产品买卖&#xff0c;有收入。那么所有这些都得记下来。记哪里&#xff1f;记在总账里…...

Redis根据中心点坐标和半径筛选符合的数据

目录 1.启动Redis​编辑 2.导入maven依赖 3.添加redis配置 4.编写RedisService 5.使用 6.验证 1.启动Redis 2.导入maven依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifac…...

springboot 集成 zookeeper 问题记录

springboot 集成 zookeeper 问题记录 环境 springboot - 2.7.8 dubbo - 3.1.11 dubbo-dependencies-zookeeper-curator5 - 3.1.11 模拟真实环境&#xff0c;将 windows 上的 zookeeper 迁移到虚拟机 linux 的 docker 环境 failed to connect to zookeeper server 迁移到…...

java中的接口interface

一、面向对象基本概念 Java是一种面向对象的语言&#xff0c;其中「对象」就相当于是现实世界中的一个个具体的例子&#xff0c;而「类」就相当于是一个抽象的模板&#xff0c;将抽象的概念模板转化为具体的例子的过程就叫做「实例化」。 比如说人这个概念就是一个抽象化的「…...

多个git提交,只推送其中一个到远程该如何处理

用新分支去拉取当前分支的指定commit记录&#xff0c;之后推送到当前分支远程仓库实现推送指定历史提交的功能 1.查看当前分支最近五次提交日志 git log --oneline -5 2.拉取远程分支创建临时本地分支 localbranch 为本地分支名 origin/dev 为远程目标分支 git checkout …...

uniapp中input的disabled属性

uniapp中input的disabled属性&#xff1a; 小程序中兼容性好&#xff1b; 在H5中兼容性差&#xff1b; 在H5中使用uniapp的input的disabled属性&#xff0c;属性值只能是true或false&#xff0c;如果为0&#xff0c; "都会为true&#xff1b; <input class"in…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...