浅析单调队列

单调队列

单调队列有两个性质:

1.队列中元素其对应在原列表中的位置为单调递增的。

2.队列中的元素为单调递增或单调递减。

单调队列不同于普通队列的操作是:单调队列可以同时从队首及队位弹出元素,从而维护队列单调性 

那么熟悉stl的小伙伴可以迅速想到,我们可以利用双端队列(deque)来实现这个过程

以下为单调队列代码,代码中有具体解释。(题目链接https://www.luogu.com.cn/problem/P1886) 

​
#include <cstdio>
#include <deque>//双端队列头文件 
#define Maxn 1000005
using namespace std;
struct node{
	int num,val;
};//记录每一个元素在原序列中对应的下标及大小 
deque<node>q1,q2;
int n,k,cnt;
int ans[3][Maxn];//ans[1][]记录最大值 ans[2][]记录最小值 
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		while(!q1.empty()&&i-k>=q1.front().num) q1.pop_front();
		while(!q2.empty()&&i-k>=q2.front().num) q2.pop_front();//如果队列不为空且队首元素的下标位置超出了当前所需查找的范围,队首弹出 
		node now;
		now.num=i,now.val=x;//记录当前元素大小及下标 
		while(!q1.empty()&&x>=q1.back().val) q1.pop_back();//如果队尾元素小于当前元素,队尾弹出,因为q1存储的是最大值,是一个单调递减序列 
		while(!q2.empty()&&x<=q2.back().val) q2.pop_back();//如果队尾元素大于当前元素,队尾弹出,因为q2存储的是最小值,是一个单调递增序列 
		q1.push_back(now),q2.push_back(now);//队尾压入当前元素 
		if(i>=k){
			ans[1][++cnt]=q1.front().val;
			ans[2][cnt]=q2.front().val;//此时两个队列对手存储的即为当前区间内的最大值及最小值 
		}
	}
	for(int i=1;i<=cnt;i++){
		printf("%d ",ans[2][i]);
	}
	printf("\n");
	for(int i=1;i<=cnt;i++){
		printf("%d ",ans[1][i]);
	}//输出 
	return 0;
}

​

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值