随笔 - 3  文章 - 0  评论 - 0  阅读 - 76

单调栈

单调栈与普通栈的区别

同样作为一种FILO (后进先出)的数据结构, 单调栈在普通栈的基础上增加了一个要求: 栈内元素必须严格单调递增或单调递减
栈顶到栈底严格递增的栈叫单调递增栈, 栈顶到栈底严格递减的栈叫单调递减栈

单调栈原理

元素进栈 (以单调递增栈为例):
e 是一个待进栈的元素, 从栈顶到栈底遍历元素, 直到栈为空或找到第一个比 e 大的元素才能让 e 进栈

由于一共只需操作 n 个元素, 所以时间复杂度为 O(n)

实现

模板: 后面第一个大于

题面

有一个长度为 n(1n30000) 的序列 a(30ai100) , 对于每个 i , 求最小的 j 满足 i+j<=nai+j>ai, 如果没有则输出 0

输入样例

8 73 74 75 71 69 72 76 73

输出样例

1 1 4 2 1 1 0 0

思路

倒着遍历, 用单调递减栈维护序列, 插入时不断弹出小于等于当前数的, 直到发现第一个大于的再进栈。时间复杂度 O(n)
(如果是正着遍历那么每个数的答案都将为0)

code
#include<bits/stdc++.h>
using namespace std;
const int N=30010;
int a[N],n,res[N];
stack<int>st;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=n;i>=1;i--){
		while(!st.empty()&&a[st.top()]<=a[i]) st.pop();
		if(st.empty()) res[i]=0;
		else res[i]=st.top()-i;
		st.push(i);
	}
	for(int i=1;i<=n;i++) printf("%d ",res[i]);
	return 0;
}
posted on   Junhan_Yang  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示