一道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刷题!!!🍗🍗

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