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("
");
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题解时,傻乎乎的就没有打这个特判,要注意哦。
同样,队列最大只能和窗口一样大,否则窗口不给撑爆了?当窗口比队列长度小的时候,要让队首指针向前挪一个单位。
然后再输出就好了。
最后想说:单调栈不能算是一个数据结构,本质上是一种算法,就像单调栈一样(不知道单调栈的戳这)。要多理解哦!