单调栈与单调队列
1.单调栈
单调栈就是去除永远用不到的数据,可以让让栈里面的数据永远有单调性。如果满足这个条件就可以用单调栈来优化。
例:acwing-830-单调栈
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int stk[N];
int tt;
int main()
{
cin.tie(0);
int m;
cin>>m;
for(int i=0;i<m;i++)
{
int x;
cin>>x;
while(tt && stk[tt] >= x) tt--;//每次用栈顶元素和输入的元素比较,逆序对直接删除
if(tt) cout<<stk[tt]<<' ';
else cout<<"-1"<<' ';
stk[++ tt] = x;
}
return 0;
}
2.单调队列。
和单调栈一样去除不需要的数据来保持单调。如果满足这个条件就可以用单调队列来优化。
例:acwing-154-滑动窗口
//这个题的主要思想是用一个队列来维护每一个窗口,如果队尾的元素永远用不到,就将其换成新插入的数据。然后依次判断
//每一个窗口输出队头的值即是最优解
//因为这里的每一个有效值可能要用多次,所以必须要用一个队列来维护,而不是直接在原数组上进行操作。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[N],q[N];
int main()
{
int n,k;
cin>>n>>k;
int hh=0,tt=-1;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(i-k+1>q[hh]) hh++;
while(hh<=tt && a[q[tt]] >= a[i]) tt--;//这里的q[tt]存的是下标
q[++tt] = i;//每一次的下标都存到队尾来便于将它所对应的值和下一次新插入的元素进行比较
if(i>=k-1) cout<<a[q[hh]]<<' ';
}
cout<<endl;
hh=0,tt=-1;//这里求最大值和上面求最小值是对称的。
for(int i=0;i<n;i++)
{
if(i-k+1>q[hh]) hh++;
while(hh<=tt && a[q[tt]] <= a[i]) tt--;
q[++tt] = i;
if(i>=k-1) cout<<a[q[hh]]<<' ';
}
return 0;
}
至于用单调栈还是单调队列要视具体情况来定。=> 如果需要在两边进行操作就选择单调队列;如果只需要在尾部进行操作就选择单调栈。