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

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

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

八月更文结束,最后一天双更,以后更新周期可能会变长,但文章也会更好更长(欢迎关注互相交流),比如这个单调栈小系列就可以融为一篇 🍉

Preface

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

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

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

照例贴出单调栈模板:

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

84. 柱状图中最大的矩形

Description

image-20210828161718263

Simulation

思路分析:

  1. 大眼一瞧,柱状图高高低低,计算面积,这不是接雨水吗?单调栈确认!

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

    image-20210830221122439

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

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


单调栈小系列终于更完了,求个赞不过分吧!

欢迎关注互相交流 💖💖 有问题可以评论留言我一定回!

我是Mancuoj,更多有趣文章:Mancuoj 的个人主页

文章分类
代码人生
文章标签