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

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

Preface


上篇讲了一道单调栈Hard题接雨水,这篇来讲一道很类似但细节有很大不同的Hard题柱状图中最大的矩形 - 力扣


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


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


照例贴出单调栈模板:


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


84. 柱状图中最大的矩形


Description



image.png

image.png


Simulation


思路分析:


  1. 大眼一瞧,柱状图高高低低,计算面积,这不是接雨水吗?单调栈确认!
  2. 判断单调性?可以看到图中都是遇到小值需要出栈的时候才计算面积,可以确认是递增的栈,也就是栈顶元素最大。单调性确定!直接三板斧给出:


image.png



  1. 单调栈存入下标计算宽度,根据出栈的最小值计算高度(具体思路上篇文章已经详细给出,在此不赘述)删改后可得:


for (int i = 0; i < h.size(); i++) {
    while (!stk.empty() && h[i] < h[stk.top()]) { // 出栈条件
        int pre = stk.top();  // 保存要出栈的元素
        stk.pop();
        if (!stk.empty()) {   // 计算面积
            int height = h[pre];
            int width = i - stk.top() - 1;
            res = max(res, height*width); // 保留更大的值
        }
    }
    stk.push(i);
}
复制代码


但这样就足够了吗?显然不行,设想两种情况:


  1. 输入两个元素[2,5],本身递增可以直接入栈,没有出栈怎么计算面积?
  2. 输入任意一个元素,怎么计算面积?


其实解决方法很简单,我们只要在数组前后各加一个0就可以了。0一定是最小元素,在前面加一个0不用担心栈空的情况,每次出栈都计算一下面积;没有出栈条件就创造出栈条件,所以在数组后面加一个0。


h.insert(h.begin(), 0);   // 前插一个0
h.push_back(0);     // 后插一个0
复制代码


Solution


完整代码如下:


class Solution {
public:
    int largestRectangleArea(vector<int>& h) {
        stack<int> stk;
        int res = 0;
        h.insert(h.begin(), 0);
        h.push_back(0);
        for (int i = 0; i < h.size(); i++) {
            while (!stk.empty() && h[i] < h[stk.top()]) { // 出栈条件
                int pre = stk.top();  // 保存要出栈的元素
                stk.pop();
                // 栈不会空
                int height = h[pre];
                int width = i - stk.top() - 1;
                res = max(res, height*width); // 保留更大的值
            }
            stk.push(i);
        }
        return res;
    }
};
复制代码


Conclusion


可以看到这道题跟接雨水虽然相似,但麻烦了许多,特殊值的输入给我们的解题思路带来了一定困扰,不过你不能指望Hard题都是套个模板就能AC的。


虽然三板斧很好用,但一些特殊条件的计算仍然是需要你自己的判断,那么问题来了:怎么提高自己的能力?


我这里有好康的:力扣单调栈题库

刷题!刷题!还是TMD刷题!!!🍗🍗

目录
相关文章
|
2月前
LeetCode 热题100——单调栈
LeetCode 热题100——单调栈
24 0
|
2天前
|
存储 算法 索引
力扣每日一题 6/24 模拟 数组 单调栈
力扣每日一题 6/24 模拟 数组 单调栈
6 0
|
16天前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
20天前
|
存储 算法 数据可视化
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
|
17天前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
|
20天前
|
存储 SQL 算法
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
|
20天前
|
存储 SQL 算法
LeetCode 题目 94:五种算法递归|迭代|莫里斯|线索二叉树|栈的迭代二叉树 实现中序遍历
LeetCode 题目 94:五种算法递归|迭代|莫里斯|线索二叉树|栈的迭代二叉树 实现中序遍历
|
21天前
|
SQL 算法 数据挖掘
探索有效括号 力扣第20题:从栈到递归的多角度解法 【含图解 python】
探索有效括号 力扣第20题:从栈到递归的多角度解法 【含图解 python】
|
2月前
|
索引
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
23 0
|
2月前
|
缓存 算法 C语言
数据结构与算法⑧(第三章_上)栈的概念和实现(力扣:20. 有效的括号)
数据结构与算法⑧(第三章_上)栈的概念和实现(力扣:20. 有效的括号)
15 0