一道Medium,两道Hard带你刷爆力扣单调栈(二)

简介: 一道Medium,两道Hard带你刷爆力扣单调栈(二)

Preface


上篇讲了每日温度,这篇来讲一道单调栈的Hard题 接雨水 - 力扣


回忆一下上篇的解题步骤:


  1. 判断单调栈:一般来说,题目中要求找到一个元素左边(右边)第一个比自己大(小)的元素,我们应该首先想到单调栈。它的应用范围可以说是很窄,但缺点也是优点,这种题目类型很好辨认。
  2. 分析单调性: 分析时应该首先分析单调性,判断单调减还是单调增,直接给出三板斧(模板)。
  3. 计算: 在模板的基础上进行删改,计算题目要求。


照例贴出单调栈模板:


// 单调栈模板,不懂可以看我的上篇文章
 for (遍历这个数组) {
     while (栈不为空 && 栈顶元素与当前数组元素比较) {
         出栈;
     }
     入栈; 
 }
复制代码


42. 接雨水



Description


image.png


Simulation


思路:


  1. 看图分析,只有下一个大于等于自己的元素插入才会形成凹槽接到雨水。所以显而易见,我们应该使用单调栈。
  2. 单调性怎么判断?很明显,比自己小的可以直接插入,大的插入要让前面的小元素出栈,因此我们需要一个递减的栈(栈顶元素最小)。
  3. 面积怎么计算?底 ✖ 高大伙都知道,然后按行计算,下面是分析:


首先明确一下单调栈里到底要存什么内容,每个柱的高度?不不不!我们需要下标来计算宽度,而下标又可以直接get到对应的高度,所以只需一个单调栈来存储下标就可以了。


image.png



画了一张图进行模拟计算过程,一组数[2,1,0,3] 从左到右依次入栈:


  • 2入栈,栈为空,下标i直接入栈,栈内元素 i
  • 1<2,直接入栈,栈内元素 i, i+1
  • 0<1,直接入栈,栈内元素 i, i+1, i+2
  • 3>0,保存0作为基底然后出栈,计算凹槽面积:高为1,选择3与当前栈顶元素1之间小的那个(木桶理论,看短的);底为1,3的下标减去1的下标 (i+3) - (i+2) ;总面积+1,继续判断 👇
  • 3>1,保存1作为基底然后出栈,计算凹槽面积:高为1,因为1作为基底,此时栈顶元素为2,所以高为 2-1=1 ,下标计算出底为2;总面积+2,继续判断 👇
  • 3>2,2出栈,但此时栈为空,不需要继续计算。3终于入栈,最后栈内元素 i+3
  • 总面积为3


看完模拟过程,相信你已经有了思路,单调减的栈,三板斧一整,我们只需要在出栈的时候计算面积即可。下面给出完整代码 🍉🍉🍉


Solution


// hrh 8/29 
 class Solution {
 public:
     int trap(vector<int>& h) {
         stack<int> stk;    
         int res = 0;
         // 三板斧!
         for (int i = 0; i < h.size(); i++) {
             while (!stk.empty() && h[i] >= h[stk.top()]) {
                 int base = h[stk.top()];        // 保存基底然后出栈
                 stk.pop();      
                 // 栈不空时计算面积
                 if (!stk.empty()) {             
                     int height = min(h[stk.top()], h[i]) - base;
                     int width = i - stk.top() - 1;
                     res += height*width;
                 }
             }
             stk.push(i);
         }
         return res;
     }
 };
复制代码


Conclusion


再复习一下解题过程:


  1. 判断这道题能否用单调栈解决。
  2. 判断单调性,给出三板斧。
  3. 模拟计算过程,删改模板得到结果。

一道Hard题就轻松解决了~

目录
相关文章
|
6月前
|
存储 算法 测试技术
力扣经典150题第五十四题:最小栈
力扣经典150题第五十四题:最小栈
47 0
|
7月前
|
存储 算法 索引
力扣每日一题 6/24 模拟 数组 单调栈
力扣每日一题 6/24 模拟 数组 单调栈
45 0
|
3月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
19 0
|
3月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
27 0
|
5月前
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
37 6
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
36 4
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 09. 用两个栈实现队列
使用两个栈实现队列的Python解决方案,包括初始化两个栈、实现在队列尾部添加整数的appendTail方法和在队列头部删除整数的deleteHead方法,以及相应的示例操作。
43 2
|
5月前
|
Python
【Leetcode刷题Python】232. 用栈实现队列
如何使用Python语言通过两个栈来实现队列的所有基本操作,包括入队(push)、出队(pop)、查看队首元素(peek)和判断队列是否为空(empty),并提供了相应的代码实现。
25 0
|
7月前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
7月前
|
存储 算法 数据可视化
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)