单调队列---数据结构与算法

简介

队列也是一种受限制的线性表和栈相类似,栈是先进后出,而队列是先进先出,就好像一没有底的桶,往里面放东西,如图

在这里也是用数组来实现队列,用数组实现的叫做顺序队列

队列的数组模拟

const int N = 1000010;//在队尾插入元素 队头弹出元素
int q[N],hh,tt=-1; //hh代表队头 tt代表队尾//插入
q[++tt] = x ;//弹出
hh++ ;//判断队列是否为空 
if(hh <= tt ) not empty
else empty//取出队头元素
q[hh] ;

单调队列

单调队列也就是说其中的元素始终保持单调性

常见应用:找出滑动窗口中的最大值/最小值

如题:给定一个大小为 n ≤ 10^6 的数组。 有一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子: 该数组为 [1 3 -1 -3 5 3 6 7],k 为 3。

 输入格式
输入包含两行。
第一行包含两个整数 n 和 k,分别代表数组长度和滑动窗口的长度。
第二行有 n 个整数,代表数组的具体数值。
同行数据之间用空格隔开。
 输出格式
输出包含两个。
第一行输出,从左至右,每个位置滑动窗口中的最小值。
第二行输出,从左至右,每个位置滑动窗口中的最大值。
 输入样例

8 3
1 3 -1 -3 5 3 6 7

 输出样例
 

-1 -3 -3 -3 3 3
3 3 5 5 6 7

例子的输出解释: 

        窗口的位置               最小值                    最大值
【1 3 -1】 -3 5 3 6 7                -1                3
1【 3 -1 -3】 5 3 6 7                -3                3
1 3 【-1 -3 5 】3 6 7                -3                5
    1 3 -1【 -3 5 3 】6 7                -3                5
    1 3 -1 -3 【5 3 6 】7                3                6
    1 3 -1 -3 5【 3 6 7】                3                7

对于解开这题我们依旧尝试暴力做法

既然求滑动窗口中的最大值和最小值,那我们只需要让窗口滑动 n - k + 1 次,再每次都对窗口里的k个数,求出最大/小值就可以了,以下是部分代码

//求最小值
for (int i = 0 ; i < n - k + 1 ; i++)
{int min = -1;for (int j = i; j < i + k; j++){if (a[i] <= min){min = a[i];}}printf("%d ", min);
}
//求最大值
//

 这样的做法不仅要遍历数组一遍,在这个过程中窗口还要遍历,相当于遍历了 n * k 遍,非常浪费时间。

优化的方向也是和之前的单调栈类似,有很多元素根本就不可以在后边用到, 例如

我们求最小值时,当 a [ x ] >= a [ y ] 并且 x > y ,这种情况就可以将 a [ x ] 从我们这个队列删除

反之,易得。

这就得到了队列的单调性

 对于这个循环中我们需要做3个步骤

1. 检测队列是否为空 并且 队头是否滑出了窗口,这是什么意思呢?窗口的大小固定是 k ,我们要保证队列中的元素全是窗口里的数的下标,队头保存的下标如果是窗口左边的下标,就说明要将队头的元素移出队列(这里只需要判断一次,因为每次循环最多添加一个元素)

2. 检测队列是否为空 并且队尾所指向的元素是否大于等于此时的元素,如果为真,要将队尾移出队列

3.再将我们此时指向的元素的下标加入队列

4.打印最小值,肯定不是每一次循环都需要打印,你会发现前 k - 1 次不需要打印,变成 i 的话就是i >= k - 1(i从0开始),因为此时窗口都没有满

现在将以上步骤变成代码

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>using namespace std;const int N = 1000010;
int n, k;
int a[N], q[N]; //q 数组是队列
int hh, tt = -1; //hh是队头 tt是队尾int main(void)
{scanf("%d%d", &n, &k);for (int i = 0; i < n; i++){scanf("%d", &a[i]);}for (int i = 0; i < n; i++){if (hh <= tt && q[hh] < i - k + 1) hh++; // i - k + 1 就是窗口的最左边的下标while (hh <= tt && a[q[tt]] >= a[i]) tt--;q[++tt] = i;if (i >= k - 1 ) printf("%d ", a[q[hh]]);}puts(""); //打印空字符串,虽然打印为空,但是使用 puts() 显示字符串时,系统会自动在其后添加一个换行符hh = 0, tt = -1; //记得要初始化数列for (int i = 0; i < n; i++){if (hh <= tt && q[hh] < i - k + 1) hh++; while (hh <= tt && a[q[tt]] <= a[i]) tt--;q[++tt] = i;if (i >= k - 1) printf("%d ", a[q[hh]]);}puts(""); return 0;
}

运行图

成功得到结果

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

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

相关文章

Docker启动Mysql

如果docker里面没有mysql需要先pull一个mysql镜像 docker pull mysql其中123456是mysql的密码 docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql可以使用如下命令进入Mysql的命令行界面 docker exec -it mysql bash登录mysql使用如下命令,root是…

大恒IFrameData IImageData转bmp HObject Mat

大恒工业相机采集的帧数据转为其他8bit图像格式 C#转为bmp格式转为Halcon的HObject格式转为OpenCVSharp的Mat格式 回调采集图像的数据类型为IFrameData&#xff0c;单帧采集的数据类型为IImageData&#xff0c;两者的区别为IImageData类多了一个**Destroy()**方法 C# 转为bm…

typescript 分析泛型工具类Partial的实现原理理解索引查询类型

Partial实现原理 在 TypeScript 中&#xff0c;Partial 是一个非常有用的工具类型&#xff0c;它能够将一个对象类型的所有属性变为可选。Partial 的实现原理是通过使用映射类型&#xff08;Mapped Type&#xff09;和 keyof 关键字来实现的。 下面我们来看一下 Partial 的实现…

ChatGPT技术原理

Task03 ChatGPT技术原理 目录 阶段一&#xff1a;有监督微调Supervised fine-tuning (SFT)阶段二&#xff1a;训练回报模型&#xff08;Reward Model, RM&#xff09;阶段三&#xff1a;使用强化学习微调 SFT 模型 ChatGPT 是由 GPT-3 迭代来的&#xff0c;原有的 GPT-3 可能…

小程序入门笔记(一) 黑马程序员前端微信小程序开发教程

微信小程序基本介绍 小程序和普通网页有以下几点区别&#xff1a; 运行环境&#xff1a;小程序可以在手机的操作系统上直接运行&#xff0c;如微信、支付宝等&#xff1b;而普通网页需要在浏览器中打开才能运行。 开发技术&#xff1a;小程序采用前端技术进行开发&#xff0c;…

前后端通信到底是怎样一个过程

前后端通信是怎样 前言&#xff1a;Http协议 超文本传输协议 规定&#xff1a;每一次前后端通信&#xff0c;前端需要主动向后端发出请求&#xff0c;后端接收到前端的请求后&#xff0c;可以给出响应 1、Http报文 浏览器向服务器发送请求时&#xff0c;请求本身就是信息&…

Integrity Plus for Mac,保障网站链接无忧之选

在如今数字化的时代&#xff0c;网站链接的完整性对于用户体验和搜索引擎排名至关重要。如果您是一位网站管理员或者经常需要检查网站链接的人&#xff0c;那么Integrity Plus for Mac&#xff08;Integrity Plus&#xff09;将成为您最好的伙伴。 Integrity Plus是一款专业的…

国庆发生的那些事儿------编写了炫酷的HTML动态鼠标特效,超级炫酷酷酷!

文章目录 前言具体操作总结 前言 国庆假期的欢乐&#xff0c;当然少不了编码爱好者&#xff01;假期编写了炫酷的HTML动态鼠标特效&#xff0c;超级炫酷酷酷&#xff01;让你的页面变得更加炫酷&#xff0c;让你的小伙伴们羡慕的大神编码&#xff01;快来看看大神是如何编写的…

The directory ‘*‘ or its parent directory is not owned by the current user

python安装编译时出现如下错误 The directory /home/admin/.cache/pip/http or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may …

Linux学习之悟空派上实现OLED的无线网IP及CPU温度显示【守护进程】

起因 最近各种网购平台似乎都在推送99元的悟空派全志H3的开发板&#xff0c;出于好奇就买了一块来试试水&#xff0c;由于这块板子基本上和orangepi-Zero的硬件结构一模一样&#xff0c;所以设备树、boot这些就用orangepi现成的部件了。 因为本人比较喜欢使用SSH操作&#xff…

redis高可用(主从复制,哨兵,集群)

目录 一、主从复制&#xff1a; 1.主从复制介绍&#xff1a; 2.主从复制的作用&#xff1a; 3.主从复制流程&#xff1a; 4.搭建Redis 主从复制&#xff1a; 4.1 环境准备&#xff1a; 4.2 安装redis&#xff1a; 4.3 master节点修改 Redis 配置文件&#xff1a; 4.4 slave节点…

【数据结构与算法】树、二叉树的概念及结构(详解)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--树以及二叉树的概念与结构 目录 一.树概念及结构 1.树的概念 1.1树与非树 树的特点&#xff1…