单调栈与单调队列

单调栈

数组/栈中的数满足单调性质(递增或递减),可查询 \(1 - i\) 中的最小值或是最大值。

实现:(以单调上升举例)
将数按顺序压入栈中,若新压入的数小于前一个数(不满足单调性),则弹出前一个数,继续向前比较,直至满足大于前一个数(满足单调性)时将此数入队。

代码:

while(s[now] < a[i]){ //不满足条件
    now --; //弹出
} s[++ now] = a[i]; //入栈

应用:
常用于寻找一个数右侧第一个大于或是小于它的数。或是用于优化 dp 的效率。

习题:
Patrik 音乐会的等待

单调队列

类似于单调栈,但可控制区间长度,不一定是单调栈的 \(1 - i\) ,可以是 \(j - i\)

实现:
在单调栈的基础上添加控制左端点的变量。

代码:

l = 1; r = 0; //初始化左右端点位置
while(l <= r && a[i] > a[s[r]]){
	r --; //弹出
}
s[++ r] = i; //入队
while(l <= r && s[l] + k <= i){ //若长度不满足限制
	l ++; //左端点右移
}

应用:
常用于查询一段区间中的最大值或是最小值。

习题:
理想的正方形
WIL

单调栈与单调队列

单调队列灵活性比单调栈更高,可控制查询区间。但在没必要控制时直接使用单调栈即可。

posted @ 2023-07-03 15:23  Biuld  阅读(19)  评论(1编辑  收藏  举报