数据结构之单调队列

Dev.C++数据结构之单调栈:从数学上来讲,函数的单调性也可以叫做函数的增减性。当函数f(x) 的自变量在其定义区间内增大(或减小)时,函数值f(x)也随着增大(或减小),则称该函数为在该区间上具有单调性。换句话来说,函数的单调性就是在区间内的自变量只增或只减。


我们说,数学中函数在一段区间内自变量只增或只减,那么这个函数在这个区间内具有单调性。
那么,这和单队列有什么关系呢?单调队列,你可以理解为一个升序或降序队列。另外的,单调队列可以从队首出队,也可以从队尾出队。这里给出一道例题。

单调队列洛谷模板题(滑动窗口)
这里我给出一个数组代码

#include<bits/stdc++.h>
#define MAXN 1000100
using namespace std;
int k,n,a[MAXN],f,r,maxn[MAXN],minn[MAXN];
inline int read(){
    int s=0,w=1; 
	char ch=getchar();
    while(ch<'0'||ch>'9')
	{
	if(ch=='-') 
	w=-1;
	ch=getchar();
	}
    while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();	
    return s;
}
int main()
{
	n=read(),k=read();
	f=1,r=0;
	for(int i=1;i<=n;i++)a[i]=read();//scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		while(a[i]<a[minn[r]]&&r!=0)
		{
			minn[r]=0;
			--r;
		}		
		minn[++r]=i;
		if(r<f)f=r;
		if(i<k)continue;
		if(minn[f]<i-k+1)f++;
		printf("%d ",a[minn[f]]);
	}
	printf("\n");
	f=1,r=0;
	for(int i=1;i<=n;i++)
	{
		while(a[i]>a[maxn[r]]&&r!=0)
		{
			maxn[r]=0;
			--r;
		}
		maxn[++r]=i;
		if(r<f)f=r;
		if(i<k)continue;
		if(maxn[f]<i-k+1)f++;
		printf("%d ",a[maxn[f]]);
	}
}

(除了快读纯手打)
日常变量解释:

  • k、n、a题目变量
  • f、r:队首和队尾
  • maxn minn:对应题目的两行答案

这道题并不难。

它的思想就是:
①不符合单调性的出队
②该元素入队
③特判:当队尾在队首之前时,证明队首未正常刷新,进行刷新。
④重点特判:与题目有关
⑤:同④


讲解:


重点特判是什么?
首先,我们看一下题目,可以知道这是一个窗口一个窗口的扫,每次向右移1个单位。

燃鹅,我们的for是一个元素一个元素的扫。所以,要在它i指针比窗口大时,再进行运算。
这是一个重点特判,有些童鞋看luogu题解时,傻乎乎的就没有打这个特判,要注意哦。
同样,队列最大只能和窗口一样大,否则窗口不给撑爆了?当窗口比队列长度小的时候,要让队首指针向前挪一个单位。


然后再输出就好了。
最后想说:单调栈不能算是一个数据结构,本质上是一种算法,就像单调栈一样(不知道单调栈的戳这)。要多理解哦!

posted @ 2020-11-28 18:44  riced  阅读(115)  评论(0编辑  收藏  举报