怎么想到要用单调栈的?

这类题目的数据通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己或者的元素的位置(寻找边界),此时我们就要想到可以用单调栈了。

42. 接雨水

这道题就是要求解每一个柱子左边第一个比它高的柱子,以及右边第一个比它高的柱子,然后这两个柱子间形成的凹槽面积。

注意,是横向扫来求面积。比如下图,4号柱左边第一个比它高的柱子是3号,右边第一个比它高的是7号,面积是蓝色框(遍历到7号柱时才会计算面积)。

我们额外用一个栈来存储左边第一个更高柱子的编号(为什么是左边,因为用for循环遍历是从左边开始的,左边代表遍历过了的信息)。

右边第一个更高的柱子会出现在for循环遍历时,见下面的case 3。

在用for循环遍历每一跟柱子时,会出现以下三种情况,我们要根据不同情况来选择如何操作栈。

  • case 1:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
  • case 2:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
  • case 3:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]   (碰到了右边第一个更高的柱子)
    int trap(vector<int> &height)
{
int ans{0};
stack<int> stk; // 单调递增栈 for (int i = 0; i < height.size(); ++i)
{
while (!stk.empty() && height[i] > height[stk.top()]) // case 3
{
int right = i;
int mid = stk.top();
stk.pop();
if (!stk.empty())
{
int left = stk.top(); // 弹出mid后,栈顶元素就是mid左侧第一个比它高的柱子
// 计算面积
int width = right - left - 1;
int h = min(height[left], height[right]) - height[mid];
ans += width * h;
}
}
// case 1&2
stk.push(i);
}
return ans;
}

84. 柱状图中最大的矩形

42. 接雨水是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。
因此与接雨水相反,该题使用单调递增栈。
如下图,在2号柱(value: 5)柱左边第一个更小的柱子是1号柱(value: 1),右边第一个更小的柱子是4号柱(value: 2)。意味着以5为高度能贯穿两个边界这之间的柱子。

    int largestRectangleArea(vector<int> &heights)
{
stack<int> stk; // 单调递减栈
int ans{0};
heights.insert(heights.begin(), 0); // 数组头部加入元素0
heights.push_back(0); // 数组尾部加入元素0
for (int i = 0; i < heights.size(); ++i)
{
while (!stk.empty() && heights[i] < heights[stk.top()])
{
int right = i;
int mid = stk.top();
stk.pop(); int left = stk.top();
int width = right - left - 1;
int h = heights[mid];
ans = max(ans, width * h);
}
stk.push(i);
}
return ans;
}

吃透单调栈(2)——解两道Hard题:接雨水、柱状图中最大的矩形问题的更多相关文章

  1. 『ACM C++』Virtual Judge | 两道基础题 - The Architect Omar && Malek and Summer Semester

    这几天一直在宿舍跑PY模型,学校的ACM寒假集训我也没去成,来学校的时候已经18号了,突然加进去也就上一天然后排位赛了,没学什么就去打怕是要被虐成渣,今天开学前一天,看到最后有一场大的排位赛,就上去试 ...

  2. 单调栈3_水到极致的题 HDOJ4252

    A Famous City 题目大意 给出正视图  每一列为楼的高度 最少有几座楼 坑点 楼高度可以为0 代表没有楼 贡献了两发RE 原因 if(!s.empty()&&tem){s. ...

  3. Co-prime Array&&Seating On Bus(两道水题)

     Co-prime Array Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Su ...

  4. MT【327】两道不等式题

    当$x,y\ge0,x+y=2$时求下面式子的最小值:1)$x+\sqrt{x^2-2x+y^2+1}$2)$\dfrac{1}{5}x+\sqrt{x^2-2x+y^2+1}$ 解:1)$P(x,y ...

  5. MT【235】两道函数题

    已知$g(x)=x^2-ax+4a$,记$h(x)=|\dfrac{x}{g(x)}|$,若$h(x)$在$(0,1]$上单调递增,求$a$的取值范围. 解答: 已知$$g(x)=\begin{cas ...

  6. Java基础知识强化11:多态的两道基础题

    1.第1题 class Base { public void method() { System.out.print("Base method"); } } class Child ...

  7. 逛园子,看到个练习题,小试了一把(淘宝ued的两道小题)

    闲来无事,逛园子,充充电.发现了一个挺有意思的博文,自己玩了一把. 第一题:使用 HTML+CSS 实现如图布局,border-widht 1px,一个格子大小是 60*60,hover时候边框变为橘 ...

  8. [转载]2014年10月26完美世界校招两道java题

    public class VolitileTest { volatile static int count=0; public static void main(String args[]){ for ...

  9. DASCTF七月赛两道Web题复现

    Ezfileinclude(目录穿越) 拿到http://183.129.189.60:10012/image.php?t=1596121010&f=Z3F5LmpwZw== t是时间,可以利 ...

  10. 【DP/单调栈】关于单调栈的一些题目(codevs 1159,codevs 2673)

    CODEVS 2673:Special Judge 题目描述 Description   这个月的pku月赛某陈没有参加,因为当时学校在考试[某陈经常逃课,但某陈还没有强大到考试也可以逃掉的程度].何 ...

随机推荐

  1. 2015年蓝桥杯C/C++大学B组省赛真题(星系炸弹)

    题目描述: 在X星系的广袤空间中漂浮着许多X星人造"炸弹",用来作为宇宙中的路标. 每个炸弹都可以设定多少天之后爆炸. 比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在 ...

  2. Java(break、continue、label)

    1.break break在任何循环语句的主体部分,均可用break控制循环的流程.break用于强行退出循环,不执行循环中剩余的语句.(break语句也在switch语句中使用) 例如:循环输出10 ...

  3. 利用jira及confluence的API进行批量操作(查找/更新/导出/备份/删除等)

    前言: 近期因为某些原因需要批量替换掉 jira 和 confluence中的特定关键字,而且在替换前还希望进行备份(以便后续恢复)和导出(方便查看)atlassian官方的api介绍文档太简陋,很多 ...

  4. API NEWS | 三个Argo CD API漏洞

    欢迎大家围观小阑精心整理的API安全最新资讯,在这里你能看到最专业.最前沿的API安全技术和产业资讯,我们提供关于全球API安全资讯与信息安全深度观察. 本周,我们带来的分享如下: 关于三个Argo ...

  5. 将onnx的静态batch改为动态batch及修改输入输出层的名称

    目录 背景 操作 修改输入输出层 修改输入输出层名称 完整代码 背景 在模型的部署中,为了高效利用硬件算力,常常会需要将多个输入组成一个batch同时输入网络进行推理,这个batch的大小根据系统的负 ...

  6. 基于Sa-Token实现微服务之前的单点登录

    修改配置文件,准备好四个域名 127.0.0.1 auth.server.com 127.0.0.1 user.server.com 127.0.0.1 third.server.com 127.0. ...

  7. Net 编译器平台--- Roslyn Scripting APIs

    引言 上一篇中.Net 编译器平台 --- Roslyn,介绍了Roslyn的各项功能,包括公开API,使用语法,使用语义,使用工作区等功能. 那么回到上一篇中提到的问题,实现类似这样的功能(以下代码 ...

  8. java根据配置文件读取值

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> ...

  9. 1.8 运用C编写ShellCode代码

    在笔者前几篇文章中,我们使用汇编语言并通过自定位的方法实现了一个简单的MessageBox弹窗功能,但由于汇编语言过于繁琐在编写效率上不仅要考验开发者的底层功底,还需要写出更多的指令集,这对于普通人来 ...

  10. Windows电脑环境变量(用户变量、系统变量)的修改

      本文介绍在Windows 10操作系统中,进行用户变量.系统变量等两种环境变量的新建.修改与删除的详细方法.   在很多时候,我们需要对Windows电脑的环境变量加以修改,例如安装一些专业软件. ...