数据结构:单调队列

单调队列

一、性质

单调队列和单调栈很像,就是一个维护了单调性的队列数据结构,可以是单调递增的也可以是单调递减的

单调队列和普通队列的关系

1.单调队列的队首和普通的队列一样,只能删除元素

2.单调队列的队尾即可以添加元素也可以删除元素

单调队列也可以叫做输入受限的双端队列

二、单调队列的功能及作用

功能:在每次加入或者删除元素时都保持序列里的元素有序,即队首元素始终是最小值或者最大值;

作用:简单来说就是用来维护一段区间内的单调上升/下降性质,导出性质就是也可以用来维护一个区间内的最值;

为了能更好的理解单调队列,下面来举个例子

我们依次像队列中加入五个元素,5,8,2,4,1,假设队列单调递减,则队首元素始终最大,五次操作如下:

1:5

首先队列里面没有元素,把5加进去


2:8

第二个元素8大于队尾的元素所以要把5弹出,8加进去。保持队首最大


3:8 2

第三个元素2小于队尾元素,直接把2加到8后面


4:8 4

4大于队尾元素2,把2弹出,4小于8,直接将4加到8后面


5:8 4 1

1小于队尾元素4,直接把1加到4后面,队列最终为8 4 1

实现

单调队列我们用数组来进行模拟,下面是求每个长度为2的区间的最小值

首先设置队首和队尾指向的下标

注:队首指向0,队尾指向-1,默认队列里面没有元素

其次对队列

1.检查队首:如果队首指向的下标<=i-k即队首元素已经跑出了k长度即[i-k+1,i]这个区间,那么就要将队首元素弹出来,对应将h加一

2.检查队尾:如果队尾的元素>要添加的值,如果这个值加上去队列就不会保持单调性,所以要弹出队尾元素,对应t减一。目的就是保持队首元素一直是最小值且队列单调

3.加入队尾元素:q[++t]=i,首先t加一要腾出位置,加入的是元素的下标

 代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],q[N];
int n,k;
int main()
{
	cin>>n>>k;
	int h=0,t=-1;//设置队首和队尾指向的下标
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		//插入元素
		while(h<=t&&i-k>=q[h])
		{
			h++;
		 } 
		while(h<=t&&a[q[t]]>=a[i])
		{
			t--;
		}
		q[++t]=i;
		if(i>=k)//区间条件处的处理
		{
			cout<<a[q[h]]<<" ";
		}
	}
	cout<<endl;
	return 0;
 } 

输入


5 2

3 4 1 6 2

输出


3 1 1 2 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值