单调栈与队列的应用
1、单调栈一般是求数列某个数最左侧第一个大于或小于这个数的数
题目如下:
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int stk[N], top;
int n;
int main()
{
cin >> n;
while (n -- )
{
int x;
scanf("%d", &x);
while(top && stk[top] >= x) top --; //栈不空且大于这个数的话,则弹出
if(top) printf("%d ", stk[top]); //栈不空的话,栈顶则是小于它的第一个数。
else printf("-1 ");
stk[++ top] = x; //压栈
}
}
2、单调队列的典型应用,滑动窗口
题目如下:
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6+10;
int a[N], q[N];
int hh, tt = -1;
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
for (int i = 0; i < n; i ++ )
{
if(hh <= tt && q[hh] < i- k + 1) hh ++;
/*如果队头(队列存的是数组下标,q[hh]
代表队头是数组的第几个数字)已经出了窗口,则用hh++的方式让队头始终在窗口里*/
while(hh <= tt && a[q[tt]] >= a[i]) tt --;
/*如果队列不空,而且队尾元素大于当前新进队列元素,则移除队尾元素,使队列单调 */
q[++ tt] = i;
if(i >= k - 1)printf("%d ",a[q[hh]]);
}
puts("");
tt = -1, hh = 0; // 勿忘记清空队列
for (int i = 0; i < n; i ++ )
{
if(hh <= tt && q[hh] < i- k + 1) hh ++;
/*如果队头(队列存的是数组下标,q[hh]
代表队头是数组的第几个数字)已经出了窗口,则用hh++的方式让队头始终在窗口里*/
while(hh <= tt && a[q[tt]] <= a[i]) tt --;
/*同理*/
q[++ tt] = i;
if(i >= k - 1)printf("%d ",a[q[hh]]);
}
}
3、总结
牢记单调栈与队列的应用。
本文来自博客园,作者:Medjay,转载请注明原文链接:https://www.cnblogs.com/Medjay/p/15805038.html