单调队列
来源:互联网 发布:长沙优化网站排名 编辑:程序博客网 时间:2024/06/06 04:47
单调队列指的是队列中的所有元素是单调递增或者单调递减的。
它可以在队首或队尾删除元素,只能在队尾插入元素,维护队列的均摊时间复杂度为O(1)。
单调队列一般用于解决的问题如,用一个长度为k的框在所给序列上移动,求框里面所包含的元素的最大值。
以单调递减队列为例:
队尾插入元素:为了保证队列的递减性,在插入元素num的时候,要将队尾元素和num比较,如果队尾元素不大于num,则删除队尾元素,然后继续将新的队尾元素与num比较,直到队尾元素大于num,这个时候我们才将num插到队尾。
队首删除元素:其实本质上我们只需要保存包括当前元素i在内的前k个元素中的最大值,所以当队首元素的下标小于i - k + 1的时候,就说明当前队首元素的存在已经没有意义了,要将队首元素删除。
核心代码(法一):
int n, k; int a[100005],queue[100005]; void minQueue() { int head = 1, tail = 0; queue[head] = 1; for (int i = 0; i < n; i++) { //删除队首元素 if (i - queue[head] == k) head++; //直接放在队尾 if (head - tail == 1 || a[i] > a[queue[tail]]) {//第一个条件指的是队列为空 queue[++tail] = i; } else {//不断删除队尾元素找到合适位置 while (tail >= head && a[i] <= a[queue[tail]]) { tail--; } queue[++tail] = i; } if (i >= k - 1) { printf("%d%c", a[queue[head]], i == n - 1 ? '\n' : ' '); } } } void maxQueue() { int head = 1, tail = 0; queue[head] = 1; for (int i = 0; i < n; i++) { //删除队首元素 if (i - queue[head] == k) head++; //直接放在队尾 if (head - tail == 1 || a[i] < a[queue[tail]]) {//第一个条件指的是队列为空 queue[++tail] = i; } else {//不断删除队尾元素找到合适位置 while (tail >= head && a[i] >= a[queue[tail]]) { tail--; } queue[++tail] = i; } if (i >= k - 1) { printf("%d%c", a[queue[head]], i == n - 1 ? '\n' : ' '); } } }核心代码(法二):
int n, k; int a[100005];//原序列 int minQueue[100005],maxQueue[100005];//单调递减队列 单调递增队列 int minRe[100005],maxRe[100005];//结果 void solve() { int minHead = 1, minTail = 0;//单调递减序列头、尾 int maxHead = 1, maxTail = 0;//单调递增序列头、尾 for (int i = 0; i < n; i++) { //处理单调递减序列 while (minTail >= minHead && a[i] <= a[minQueue[minTail]]) { minTail--; } minQueue[++minTail] = i; if(i - minQueue[minHead] == k) minHead++; //处理单调递增序列 while (maxTail >= maxHead && a[i] >= a[maxQueue[maxTail]]) { maxTail--; } maxQueue[++maxTail] = i; if(i - maxQueue[maxHead] == k) maxHead++; //存储结果 if(i >= k - 1){ minRe[i] = a[minQueue[minHead]]; maxRe[i] = a[maxQueue[maxHead]]; } } //打印结果 for(int i = k - 1;i < n;i++){ printf("%d%c",minRe[i],i == n - 1?'\n':' '); } for(int i = k - 1;i < n;i++){ printf("%d%c",maxRe[i],i == n - 1?'\n':' '); } }
阅读全文
0 0
- 单调栈 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 持久区jvm堆内存溢出原因
- git 的常用命令总结
- centos7安装rabbitmq
- 【备忘】尚学堂白贺翔java互联网架构师视频教程下载
- 浪潮
- 单调队列
- mint UI中messagebox弹框问题
- 如何写SysV服务管理脚本
- CodeIgniter框架源码学习之控制器类--Controller.php
- PHP获取邮件
- POJ 2135 Rank List
- C语言知识复习①
- 数据结构:树----刷题集(一)
- 登陆成功页面5秒跳转