怎么想到要用单调栈的?

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

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. distribute by在spark中的一些应用

    一.在二次排序当中的应用 1.1 说到排序当然第一想到的就是sort by和order by这两者的区别,也分情况. 在算子当中,两者没有区别,orderby()调用的也是sort.order by就 ...

  2. 基于.NetCore+React单点登录系统

    对于有多个应用系统的企业来说,每一个应用系统都有自己的用户体系,这就造成用户在切换不同应用系统时,就要多次输入账号密码,导致体验非常不好,也造成使用上非常不便. 针对这个问题,我们就可以采用单点登录的 ...

  3. 代码随想录算法训练营Day55 动态规划

    代码随想录算法训练营 代码随想录算法训练营Day55 动态规划| 392.判断子序列 115.不同的子序 392.判断子序列 题目链接:392.判断子序列 给定字符串 s 和 t ,判断 s 是否为 ...

  4. SpringBoot打包成WAR包的时候把第三方jar包打到LIB文件夹下和把第三方jar包打入到SpringBoot jar包中

    SpringBoot打包成WAR包的时候把第三方jar包打到LIB文件夹下和把第三方jar包打入到SpringBoot jar包中 转载 首先我们应该知道我们把SPRINGBOOT项目打包成WAR包和 ...

  5. Dubbo远程调用在IDEA无法打断点怎么破

     以下是如何在IDEA中在Dubbo的分布式环境中设置远程调试的步骤: 1.首先,你需要在启动提供者服务时,加入一些JVM参数以开启调试服务.这些参数应该在你的启动脚本或者命令中.以下是一个常见的示例 ...

  6. 你还在用Object.equals()方法吗?

    前言 当<阿里巴巴Java开发手册>发布后,我也是仔细进行了阅读,想从中找出一些"标准",让自己的代码质量提高.手册中对 Object 的 equals 方法的使用进行 ...

  7. 【HMS Core】Android Studio安装Toolkit登录报错{"httpCode":500,"errorCode":"00012005"...

    [问题描述] 在Android Studio安装Toolkit插件,安装后登录,报错 ​ ​ [问题分析] 此种情况一般是由于开发者账户未实名造成的 [解决方案] 1.检查开发者账户是否实名,登录联盟 ...

  8. JavaCV人脸识别三部曲之二:训练

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV人脸识别三部曲&g ...

  9. 除了参数,ref关键字还可以用在什么地方?

    <老生常谈:值类型 V.S. 引用类型>中花了很大的篇幅介绍ref参数针对值类型和引用类型变量的传递.在C#中,除了方法的ref参数,我们还有很多使用ref关键字传递引用/地址的场景,本篇 ...

  10. 如何将PCM格式的原始音频采样数据编码为MP3格式或AAC格式的音频文件?

    一.打开和关闭输入文件和输出文件以及判断输入文件是否读取完毕 //io_data.cpp static FILE* input_file= nullptr; static FILE* output_f ...