单调栈

题目链接

acwing830. 单调栈
P5788 【模板】单调栈
acwing131. 直方图中最大的矩形

acwing830. 单调栈

题目描述

给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 1

输入格式

第一行包含整数 N,表示数列长度。

第二行包含 N 个整数,表示整数数列。

输出格式

共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 1

数据范围

1N105
1109

输入样例:

5 3 4 2 7 5

输出样例:

-1 3 -1 2 2
  • 时间复杂度:O(n)

代码

#include<bits/stdc++.h> using namespace std; int n; int a[100010]; stack<int> stk; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++) { while(stk.size()&&a[stk.top()]>=a[i])stk.pop(); if(stk.size()) printf("%d ",a[stk.top()]); else printf("-1 "); stk.push(i); } return 0; }

P5788 【模板】单调栈

题目描述

给出项数为 n 的整数数列 a1n

定义函数 f(i) 代表数列中第 i 个元素之后第一个大于 ai 的元素的下标,即 f(i)=mini<jn,aj>ai{j}。若不存在,则 f(i)=0

试求出 f(1n)

输入格式

第一行一个正整数 n

第二行 n 个正整数 a1n

输出格式

一行 n 个整数 f(1n) 的值。

输入

5 1 4 2 3 5

输出

2 5 4 5 0

说明/提示

【数据规模与约定】

对于 30% 的数据,n100

对于 60% 的数据,n5×103

对于 100% 的数据,1n3×1061ai109

  • 时间复杂度:O(n)

代码

#include<bits/stdc++.h> using namespace std; int n,a[3000010]; stack<int> stk,stk_res; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=n;i;i--) { while(stk.size()&&a[i]>=a[stk.top()])stk.pop(); if(stk.size()) stk_res.push(stk.top()); else stk_res.push(0); stk.push(i); } while(stk_res.size()) printf("%d ",stk_res.top()),stk_res.pop(); return 0; }

acwing131. 直方图中最大的矩形

题目描述

直方图是由在公共基线处对齐的一系列矩形组成的多边形。

矩形具有相等的宽度,但可以具有不同的高度。

例如,图例左侧显示了由高度为 2,1,4,5,1,3,3 的矩形组成的直方图,矩形的宽度都为 1

image

通常,直方图用于表示离散分布,例如,文本中字符的频率。

现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。

图例右图显示了所描绘直方图的最大对齐矩形。

输入格式

输入包含几个测试用例。

每个测试用例占据一行,用以描述一个直方图,并以整数 n 开始,表示组成直方图的矩形数目。

然后跟随 n 个整数 h1hn

这些数字以从左到右的顺序表示直方图的各个矩形的高度。

每个矩形的宽度为 1

同行数字用空格隔开。

当输入用例为 n=0 时,结束输入,且该用例不用考虑。

输出格式

对于每一个测试用例,输出一个整数,代表指定直方图中最大矩形的区域面积。

每个数据占一行。

请注意,此矩形必须在公共基线处对齐。

数据范围

1n100000,
0hi1000000000

输入样例:

7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0

输出样例:

8 4000

解题思路

单调栈

我们利用单调栈找到每个矩形 k 左右第一个比它小的矩形 i,j,则这个矩形形成的面积为 h[k](ji1),需要注意的是,单调栈里的每个元素的左边即为该元素左边比它小的第一个元素,同时通过这个单调栈还能求出右边的第一个元素

遍历当前元素时,此时栈顶作为我们的基准矩形,其左边比它小的第一个元素即次栈顶元素,当当前元素比栈顶元素小时,当前元素就是右边第一个比栈顶元素小的第一个元素,不妨假设在栈顶元素和当前元素中间还有一个比栈顶元素小的元素,则在当前元素之前,栈顶元素是会被更新的,与当前的栈顶元素矛盾,故当前元素就是栈顶元素右边第一个比栈顶元素小的元素。这里为使所有元素都出栈,增加了一个很小的元素~

  • 时间复杂度:O(n)

代码

#include<bits/stdc++.h> using namespace std; int h[100005],n; stack<int> stk; int main() { while(scanf("%d",&n),n) { for(int i=0;i<n;i++)scanf("%d",&h[i]); h[n]=-1; while(stk.size())stk.pop(); long long res=0; for(int i=0;i<=n;i++) { while(stk.size()&&h[i]<h[stk.top()]) { int cur=stk.top(); stk.pop(); if(stk.size())res=max(res,1ll*h[cur]*(i-stk.top()-1)); else res=max(res,1ll*i*h[cur]); } stk.push(i); } printf("%lld\n",res); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15320037.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(66)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示