第44期:数据结构-单调队列

本文介绍了如何使用单调队列数据结构解决滑动窗口问题,展示了在O(n)时间内找到数组中连续子数组的最大值和最小值,适合竞赛编程和算法优化实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:

单调队列 - OI Wiki

1. P1886 滑动窗口 /【模板】单调队列

#include<bits/stdc++.h>
#include<stack>
using namespace std;
const int maxn=1e6+5;
int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int n,k,a[maxn];
int q[maxn],head,tail,p[maxn];//q是单调队列,p是对应编号
void _max(){//单调最大值
	head=1;
	tail=0;
	for(int i=1;i<=n;++i){
		while(head<=tail&&q[tail]<=a[i]) tail--;
		q[++tail]=a[i];
		p[tail]=i;
		while(p[head]<=i-k) head++;
		if(i>=k) cout<<q[head]<<" ";
	} 
	cout<<"\n";
}
void _min(){
	//因为head要严格对应首元素,tail要严格对应尾元素,所以当tail>=head时,说明有元素。而一开始队列为空,说一要这样赋值。其实这跟普通队列一样。
	head=1;
	tail=0;
	for(int i=1;i<=n;++i){
		//a[i]表示当前要处理的值
		while(head<=tail&&q[tail]>=a[i]) tail--;
		//只要队列里有元素,并且尾元素比待处理值大,即表示尾元素已经不可能出场,所以出队。直到尾元素小于待处理值,满足"单调"。
		q[++tail]=a[i];//待处理值入队。
		p[tail]=i;//同时存下其编号
		while(p[head]<=i-k) head++;
		//如果队首元素已经"过时",出队。
		if(i>=k) cout<<q[head]<<" ";
		//输出最值,即队首元素。i>=k表示该输出,至于why就自己看题目 
	}
	cout<<"\n";
}
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;++i) cin>>a[i];
	_min();
	_max();
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值