数组实现栈
#include<iostream>
using namespace std;
const int N=100010;
int stk[N],tt;
//插入
stk[++tt]=x;
//弹出
tt--;
if(tt>0)not empty
else empty
//栈顶
stk[tt]
//在队尾插入,队头弹出
int q[N],tt,hh;
//弹出
tt++;
//插入
q[++hh]=x;
if(hh<tt)not empty
else empty
单调栈常见题型
给定序列,求每一个数的左边离他最近且比他小的数在什么地方
1.双指针枚举
for (int i=0;i<n;i++){
for(int j=i-1;j>=0;j--){
if(a[j]<a[i]){
cout<<j<<endl;
break;
}
}
}
栈:
#include<iostream>
using namespace std;
const int N=100010;
int stk[N],tt;
int n;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
int x=0;
scanf("%d",&x);
while(tt&&stk[tt]>=x)tt--;
if(tt)printf("%d",tt);
else cout<<-1<<endl;
stk[++tt]=x;
}
}
队列应用:滑动窗口的最大值最小值
1.暴力枚举:
遍历队列
#include <iostream>
using namespace std;
const int N = 1000010;
int a[N], q[N];
int main()
{
int n, k;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
int hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
if (hh <= tt && i - k + 1 > 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("");
hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
if (hh <= tt && i - k + 1 > 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("");
return 0;
}