单调队列的使用

单调队列其实就是一个队列,只是使用了一点巧妙的方法使得队列中的元素全都是单调递增(或单调递减)的

单挑队列主要解决以下问题:

滑动窗口在滑动时,r++代表右侧数字进入串口,l++代表左侧数字出窗口

这个过程中,想随时得到当前滑动窗口的最大值或最小值

 滑动窗口最大值

具体操作

首先我们先讨论滑动窗口加入数字后,单调队列的情况(也就是r ++ )

假设这个数组为[6,5,4,3,5,6]

注意我们这个单调队列里只放数组元素的下标,并且里面的下标对应的数值大小是从大到小的

因此我们先放入下标0(也就是a[0]),然后再放入下标1,再放入下标2,再放入下标3

此时碰到了下标4(也就是a[4] = 5)

因为我们是必须严格按照从大到小

所以弹出下标1,2,3

再放入下标4

然后碰到了下标5(也就是a[5] = 6)

弹出下标4,0

放入下标5

那滑动窗口中减少数字后,单调队列的操作又该怎么办呢?

我们假设数组为[6,5,4,3,5,6]

假设此时单调队列为

当窗口减少数字(也就是 l ++)

我们就要判断单调队列的头元素是否为过期下标(就是头元素小于 l )

如果是过期下标就把它从头部弹出

解释:

关键点:维持可能性

假设一个队列

我们先放入下标0( a[0] )

如果此时就要求滑动窗口的最大值,那它就是单调队列的头元素

然后我们再放入下标1( a[1] )

为什么要放在下标 0 ( a[0] )的右边?

因此此时滑动窗口的最大值仍然是下标0( a[0] )

但是如果此时让下标 0 ( a[0] )弹出的话(也就是 l ++),此时下标 1 ( a[1] )就是头元素(也就是最大值)

然后我们再放入下标2( a[2] ),它自然也就是放在了下标 1 ( a[1] )的右边(它也有可能会成为最大值)

注意:我们单调队列的存储的都是下标

此时要放入下标4( a[4] )

那我们为什么要弹出1,2,3?

因为它们再也没有机会变成最大值了(因为4位置一定会比1,2,3位置要晚过期,并且4位置的值比1,2,3位置都要大)

 那为什么不弹出6?

因此此时滑动窗口的最大值是下标0( a[0] )。

当 l ++时

把 0 从头部弹出

整体的复杂度为o(n)

解题思路:

1.我们先生成 k - 1 的窗口,把它放入单调队列中

2.放入一个元素(r++),放入单调队列中(此时窗口长度为k)

3. l ++ ,考虑单调队列中是否有过期下标(此时窗口长度为k-1)

不断重复2,3

代码:

# include <stdio.h>int main()
{int k;// 滑动窗口大小 int n; //数组长度 scanf("%d %d", &k, &n)int num[n];for (int i=0; i<n; ++i)scanf("%d", &num[i]);int deque[n] //单调队列int h,t; // 用于更新单调队列 h表示头元素的下标,t表示下一个元素该放的位置//当h == t 时表示单调队列里没有元素h = 0;t = 0;	 //先形成k-1的窗口 for (int i=0; i<k-1; ++i){while (h<t && num[deque[t-1]] <= num[i])t = t - 1; //直接将deque的元素进行覆盖 deque[t] = i;t++;}int m = n - k + 1; //进行的次数//当前窗口为k-1长度for (int l=0, r=k-1; l<m; ++l, ++r){//少一个,要让r位置进去while (h<t && num[deque[t-1] <= num[r]])t = t - 1;deque[t] = r;t = t + 1;//让l位置的数出去if (deque[h] == l)h = h + 1;} 
}

算法讲解054【必备】单调队列-上_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV11h4y1w7Bu/?vd_source=617dcf7ed08ed9625bdfcadc93c4fac7

拓展

除了单调队列最经典的用法之外,在很多问题里单调队列还可以维持求解答案的可能性

1.单调队列里的所有对象按照规定好的单调性来组织

2.当某个对象从队尾进入单调队列时,会从队头或者队尾依次淘汰单调队列里,对后续求解答案没有帮助的对象

3.每个对象一旦从单调队列弹出,可以结算此时这个对象参与的答案,随后这个对象不再参与后续求解答案的过程

4.其实是先有对题目的分析!进而发现单调性,然后利用单调队列的特征去实现

题目:

(一)

假设arr[1,1,1,6,8,2,9,1,5,4,1]

思路:

当我们遍历到 i 下标时,如果子数组必须以 i 为右边界,那么要往左延伸最短的距离能使累加和大于等于k

我们求出一部分的前缀和为

我们必须要找到某一段的前缀和大于等于k,然后再以它右边界的数字为结尾的情况下,向左延伸最短的距离能使累加和大于等于k

例如:

当k = 10时

0~4,它们的前缀和是17,所以我们要找到前面的某段的前缀和小于等于7,且足够靠右,把这段删去,这样就能得到某一段的前缀和大于等于k,并且向左延伸最短的距离能使累加和大于等于k。

0~2的前缀和是3,并且是足够靠右的,所以删去后,得到3~4的前缀和为14,长度为2,满足条件

因此我们可以得到统一的规律:

我们首先要找到以 i 为结尾的前缀和为 x ,并且 x >= k,

要想找到一段的前缀和大于等于k,并且长度最短

必须要删去一段前缀和小于等于 x - k,并且足够靠右的

我们建立一个单调队列

存储的是前缀和的下标,下标对应的数值大小是从小到大的

假设arr[1,1,1,6,8,2,9,1,5,4,1]

前缀和为:

k 为 10

下一个为就是4位置,此时0~4的前缀和为17,大于10,开始判断所有的可能

先判断队头

0~0的前缀和为1,那么1~4的和就是16,符合条件,所以ans = 4

然后把 0 从头部弹出(没有这种0~0的可能性了,因为我们判断出来1~4是符合条件的,我们要求最短的达标子数组,后面的数组肯定会从 1~4 开始往后计算,不会从0开始。换句话说,即使后面的子数组用上了0~0,那它的长度肯定不如是 1~4 短)

继续进行判断队头

0~1的前缀和为2,那么2~4的和就是15,符合条件,所以ans = 3

然后把1从头部弹出

继续进行判断队头

0~2的前缀和为3,那么3~4的和就是14,符合条件,所以ans = 2

然后把2从头部弹出

继续进行判断队头

0~3的前缀和为7,那么4~4的和就是8,不符合条件

然后把 4 从队尾放入单调队列

然后不断进行判断……

综上:

在单调队列中,不断放入前缀和的下标,如果遇到下标对应的前缀和大于等于k,则进行判断

如果我们遇到了负数呢:

看以下的情况:

以上为原数组

假设k = 100

此时我们依次放入前缀和的下标

下一个该放入的前缀和下标为3(0~3的前缀和是6)

那么我们就要把0,1,2全部从队尾弹出

(这里就解释了为什么要从小到大进行排列,和为什么要进行弹出操作:1.如果再继续进行下去,如碰到了一个前缀和为 x ,此时x >= k,如果此时x - 6都不符合条件(也就是x - 6 < k),那么x - 14一定是不符合条件的,所以必须要从小到大进行排列。2.因为后加入的数字,与对应的符合条件的 i 点距离肯定是更近的,所以可以把大于等于它的数字都弹出。)

然后和上面相同,不断的进行判断

代码:

# include <stdio.h>int main()
{int kint a[11];scanf("%d", &k);for (int i=1; i<=10; ++i)scanf("%d", &a[i]);int deque[10];int h, t = 0;int md[11];md[0] = 0;md[1] = a[1];for (int i=2; i<=10; ++i)md[i] = md[i-1] + a[i];int ans = 999;int k = 1;for (int i=1; i<=10; ++i){while(h !=t && md[i]-md[deque[h] >=k){ans = min(ans, i - deque[h]);h = h + 1;}while (h < t || md[deque[t-1]]> md[i])t = t - 1;deque[t] = i;t = t + 1;}}
}

(二)

因为 xi 始终大于 xj

所以我们可以直接把绝对值拆掉

所以题目就变为了求 yi + yj + xj - xi = yj + xj + yi - xi;

因此我们可以建立一个滑动窗口的单调队列

里面的元素的是yi - xi的值的下标,从大到小排列

代码:

# include <stdio.h>int main()
{//存储 i号点的 x,y int points[100][2];for (int i=0; i<100; ++i)scanf("%d %d", &points[i][0], &points[i][1]);int deque[100][2];int h, t = 0;int k;int ans = 0;for (int i=0; i<100; ++i){int x = points[i][0];int y = points[i][1];while (h < t && deque[h][0] + k < x)h = h + 1;if (h < t){ans = max(ans, deque[h][1] - deque[h][0] + x + y);}while (h < t && deque[t-1][1] - deque[t-1][0] <= y - x)t = t - 1;}deque[t][0] = x;deque[t][1] = y;t = t + 1;}

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

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

相关文章

Spring事件发布监听器ApplicationListener原理- 观察者模式

据说监听器模式也是mq实现的原理, 不过mq我还没来得及深入学习, 先用spring来理解一下吧 Spring事件发布监听器ApplicationListener原理- 观察者模式 什么是观察者模式一个Demo深入认识一下观察者模式Spring中的事件发布监听ps 什么是观察者模式 大家都听过一个故事叫做烽火戏…

数据结构与算法-希尔排序

引言 在计算机科学中&#xff0c;数据结构和算法是构建高效软件系统的基石。而排序算法作为算法领域的重要组成部分&#xff0c;一直在各种应用场景中发挥着关键作用。今天我们将聚焦于一种基于插入排序的改进版本——希尔排序&#xff08;Shell Sort&#xff09;&#xff0c;深…

证明高维度神经网络模型是低纬度神经网络模型的加和

神经网络中矩阵乘法的分解与应用 启发标题&#xff1a;神经网络中矩阵乘法的分解与应用摘要&#xff1a;引言&#xff1a;方法&#xff1a;实验&#xff1a;结论&#xff1a;参考文献&#xff1a;附录1附录2实验数据 启发 理论上 更具矩阵乘法 A[p,mn]B[mn,q]C[p,q] Acat(A[:,…

AAC ADTS格式

AAC⾳频格式&#xff1a;Advanced Audio Coding(⾼级⾳频解码)&#xff0c;是⼀种由MPEG-4 标准定义的有损⾳频压缩格式&#xff0c;由Fraunhofer发展&#xff0c;Dolby, Sony和AT&T是主要的贡献者。 ADIF&#xff1a;Audio Data Interchange Format ⾳频数据交换格式。这…

一次奇特的应急响应

访问polling.oastify.com 今天&#xff08;2024/3/5&#xff09;在深信服防火墙用户安全日志页面&#xff0c;检测到我的主机在和polling.oastify.com域名进行通信 当时通知我检查我的主机&#xff0c;慌得一批&#xff0c;检查完后可能认为是我代理的问题&#xff0c;把代理关…

w2v参数报错_TypeError: init() got an unexpected keyword argument ‘size‘

1.错误方式 w2v Word2Vec(docs,size16, sg1, window5, seed2020, workers24, min_count1, iter1) 在linux操作环境下&#xff0c;报错显示&#xff1a; TypeError: init() got an unexpected keyword argument ‘size’ 在vscode软件上&#xff0c;查看当前w2v参数 2.正确…

unocss 究竟比 tailwindcss 快多少?

unocss 究竟比 tailwindcss 快多少&#xff1f; 前言 我们知道 unocss 很快&#xff0c;也许是目前最快的原子化 CSS 引擎 (没有之一)。 unocss 解释它为什么这么快的原因&#xff0c;是因为它不用去解析 CSS 抽象语法树&#xff0c;直接在 content 里面通过正则表达式从内容…

yum 和 rpm

rpm说明 rpm -qa &#xff1a;列出所有已安装的软件包 [roothub ~] rpm -qa geoipupdate-2.5.0-1.el7.x86_64 ncurses-base-5.9-14.20130511.el7_4.noarch libndp-1.2-9.el7.x86_64 libfastjson-0.99.4-3.el7.x86_64 。。。 rpm -qf FILENAME &#xff1a;查找提供 FILENAME…

Nginx使用—http基础知识

web访问流程 当我们在客户端通过浏览器输入网址的时候&#xff0c;这时候是访问不到服务器的&#xff0c; 先会去找到DNS解析服务器&#xff0c;DNS解析服务器返回IP地址&#xff0c; 客户端通过http协议向服务端发送请求&#xff0c;服务器响应请求并返回对应的资源给客户端&a…

H5小游戏,斗地主

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的,私信本人,发演示地址,可以后再订阅,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、开心消消乐、扑鱼达人、飞机大战等等 <!DOCTYPE html> <html> <…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:组件内容模糊)

为当前组件添加内容模糊效果。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 foregroundBlurStyle foregroundBlurStyle(value: BlurStyle, options?: ForegroundBlurStyleOptions) 为当前组件提供…

北京Excel表格线下培训班

Excel培训目标 熟练掌握职场中Excel所需的公式函数计算&#xff0c;数据处理分析&#xff0c;各种商务图表制作、动态仪表盘的制作、熟练使用Excel进行数据分析&#xff0c;处理&#xff0c;从复杂的数据表中把数据进行提取汇总 Excel培训形式 线下面授5人以内小班&#xff…

最新AI系统ChatGPT网站H5系统源码,支持Midjourney绘画

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

外包干了6个月,技术退步明显

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

UE4c++ 材质功能大全(想起来就补充一个)

前言&#xff1a;才想起写一个这个文档&#xff0c;前期内容较少&#xff0c;其他内容&#xff0c;我也只会想起来加一加&#xff01; 材质功能大全 竖直百分比进度HSV To RGBRGB转灰度值AlphaComosote(Premultiplied Alpha&#xff09;预乘 转 Translucent &#xff08;sRGB与…

Hello World!第一个labview程序

软件版本&#xff1a; labview myrio 2021英文版 因为没有找到中文版的&#xff0c;据说是myrio没有中文版本 实验内容&#xff1a; 文本显示&#xff0c;程序界面输入任意文本&#xff0c;然后运行程序 在前面板显示出输入的文本 以下为具体步骤&#xff1a; 第一步&…

【数据结构和算法初阶(C语言)】复杂链表(随机指针,随机链表的复制)题目详解+链表顺序表结尾

目录 1.随机链表的复制 1.2题目描述 1.3题目分析 1.4解题&#xff1a; 2.顺序表和链表对比 2.1cpu高速缓存利用率 3.结语 1.随机链表的复制 一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random 该指针可以指向链表中的任何节点或空节点。 1.2题目描…

Godot自定义控件样式语法解析

前言 本篇原始文章写于2023年8月7日&#xff0c;存储在我的语雀文档中。但是语雀分享有诸多不便&#xff0c;为了让更多Godoter更轻松的搜到和看到&#xff0c;就转过来了。 这个项目我上传了Github&#xff0c;后续会贴上链接。 概述 Godot控件体系存在的问题之一就是样式无…

【pyinstaller打包记录】Windows系统打包exe后,onnxruntime报警告(Init provider bridge failed)

简介 PyInstaller 是一个用于将 Python 程序打包成可执行文件&#xff08;可执行程序&#xff09;的工具。它能够将 Python 代码和其相关的依赖项&#xff08;包括 Python 解释器、依赖的模块、库文件等&#xff09;打包成一个独立的可执行文件&#xff0c;方便在不同环境中运行…

凌风 TEMU工具箱 抢仓 库存销售数据利润计算 选品监控采集上品 一网打尽

凌风TEMU工具箱介绍 一、安装教程1、下载方式2、环境准备3、安装步骤3.1、插件安装3.2、客户端安装 4、启动软件 二、使用教程一&#xff1a;登录注册激活方法2.1 注册登录2.2 激活方式 &#xff08;激活码激活&#xff09;2.3 绑定店铺 二&#xff1a;使用方法&#xff1a;功能…