拒绝懒惰day17

写LeetCode昨天不会的两个题,用到单调栈的思路。

1.柱状图中最大矩形:

84. 柱状图中最大的矩形

难度困难1203收藏分享切换为英文接收动态反馈

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

 

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

 

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

 

示例:

输入: [2,1,5,6,2,3]
输出: 10
class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
        int rs = 0, j = heights.size();
        int high[j+2]; high[0] = 0; high[j+1]=0;
        for(int index = 1; index < j+1; index++){
            high[index] = heights[index-1];
        }
        vector<int> hset; hset.push_back(0);
        for(int i=1; i <= j+1; i++){
            while(high[hset.back()]>high[i]){//栈顶元素对应的高度大于当前高度时,
                rs = max(rs, high[hset.back()]*(i-1-hset[hset.size()-2]));//计算其对应的矩形,即为其高度*(当前元素与其栈顶前一个元素的位置的差减1),
                hset.pop_back();//最后弹出栈顶元素
            }
            hset.push_back(i);
        }
        return rs;
    }
};

如何理解矩形面积计算方式,

按照单调栈性质,一直持续入栈,栈中元素为新数组下标(这里代码为了处理起来简单,在元素组基础上首尾添加0,变成了新数组);

一直到 i=4 之前元素都是单调栈,故栈中元素为:0,1,2,3

此时栈顶元素对应的高度,high[3] = 6, high[2] = 4, high[3] = 3,都大于2,分别计算矩形的面积,与rs比较去较大者赋值给rs;

这里的矩形就是等于,以栈顶元素对应的high值作为高度,其宽度=i - 栈顶元素的前一个元素 - 1,

栈顶元素的前一个元素对应的high值是小于等于栈顶元素对应的高度的。

比如3号元素对应矩形高度就是high[3]=6, 此时栈顶元素时3,i=2,栈顶元素的前一个元素为2,宽度等于当前i-2-1=4-2-1=1;

再比如当指针i=9的时候,此时栈中元素为0,7,8(其对应的高度为0,1, 3满足单调栈的性质),此时栈顶元素为8,栈顶元素前一个是7,

矩形面积为high[8]*(i-7-1) = 3*(9-7-1)=3。

 

2.矩阵中最大矩形:

85. 最大矩形

难度困难823收藏分享切换为英文接收动态反馈

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

 

示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = []
输出:0

示例 3:

输入:matrix = [["0"]]
输出:0

示例 4:

输入:matrix = [["1"]]
输出:1

示例 5:

输入:matrix = [["0","0"]]
输出:0

最大矩形的思路,是把每一列看做是柱状图,当计算到每一行的时候,把以该行为低,该行所在列为的连续方块为高度的柱状图。

第一行的柱状图:

第二行:

第三行:

第四行:

所以每次都只需要求每一行用柱状图的最大矩形面积思路即可,注意每一行首尾加上0的处理。如果遇到0 ,这一列的高度清零;

high[i] = (matrix[row][i-1]-'0')*(high[i]+1); 这句代码的处理思路就是如果是0 高度就是0 ,如果不为0则为上一行保留的高度加1。

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.size()==0||matrix[0].size()==0){
            return 0;
        }
        int len = matrix[0].size()+2, n = matrix.size(), high[len], rs = 0;
        memset(high, 0, sizeof(high));
        for(int row = 0; row < n ;row++){
            for(int i = 1; i < len-1; i++){
                high[i] = (matrix[row][i-1]-'0')*(high[i]+1);
            }

            vector<int> hset; hset.push_back(0);
            for(int i = 1; i < len; i++){
                while(high[hset.back()]>high[i]){//栈顶元素对应的高度大于当前高度时,计算其对应的矩形,即为其高度*当前元素与其栈顶前一个元素的位置的差减1,最后弹出栈顶元素
                    rs = max(rs, high[hset.back()]*(i-1-hset[hset.size()-2]));
                    hset.pop_back();
                }
                hset.push_back(i);
            }
        }
        return rs;
    }
};

作者:nearby
链接:https://leetcode-cn.com/problems/maximal-rectangle/solution/hen-hao-by-nearby-ey64/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值