84. 柱状图中最大的矩形

这篇博客介绍了如何使用单调栈解决求解柱状图中最大矩形面积的问题。通过示例展示了算法思路,包括从左右两侧寻找边界,从而计算出每个柱子能构成的最大矩形面积,并最终找出全局的最大面积。此外,还提到了该算法同样适用于求解二维矩阵中最大的连续1子矩阵的面积问题。
摘要由CSDN通过智能技术生成

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

求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4

提示:
1 <= heights.length <=105
0 <= heights[i] <= 104
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram
解析:就是一个单调栈的问题,假设当前的点就是高,往左找比当前矮的最近的位置记录,往右也是找比当前点最近的记录,右减左乘高就是当前所能取到的最大的面积。记录最大值。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int m, maxn = 0, i;
        int l[200000], r[200000];
        stack<int> a; 
         m = heights.size();
         a.push(0);
         l[0] = 0;
         for (i = 1; i < m; i++){
           while (!a.empty() && heights[i] <= heights[a.top()]){
                a.pop();
            }
            if (!a.empty())
                l[i] = a.top() + 1;
            else l[i] = 0;
             a.push(i) ;
        }
        while (!a.empty())
            a.pop();
        a.push(m-1);
        r[m-1] = m - 1;
        for (i = m - 2; i >= 0; i--){
            while (!a.empty() && heights[i] <= heights[a.top()]){
                a.pop();
            }
            
            if (!a.empty())//如果为空则下面没有a.top(),不加这个会报错
                r[i] = a.top() - 1;
            else  r[i] = m - 1;
            a.push(i);
            
        }
        for (i = 0; i < m; i++){
            maxn = max(maxn, (r[i] - l[i] + 1) * heights[i]);
        }
        return maxn;
    }
};

```cpp
在这里插入代码片

85 最大矩形
同样的道理

/*
和84类似,记录一下每一行中当前点为终点连续的1的个数,相当于他的高,然后就可以竖着求面积
*/
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int i, j, n, m, maxn = 0, jj = 0;
        int l1[300], r1[300];
        int l[300][300];
        bool ff = false;
        n = matrix.size();
        stack<int>a;
        m = matrix[0].size();
        for (i = 0; i < n; i++){
            for (j = 0; j < m; j++){
                if (matrix[i][j] == '1'){
                    if (j > 0)
                      l[i][j] = l[i][j - 1] + 1;
                    else 
                      l[i][j] = 1;
                }else l[i][j] = 0;
            }
        }
        for (j = 0; j < m; j++){
            a.push(0);
            l1[0] = 0;
            for (i = 1; i < n; i++){
                while (!a.empty() && l[i][j] <= l[a.top()][j])
                    a.pop();
                if (!a.empty()){
                    l1[i] = a.top() + 1;
                }else{
                    l1[i] = 0;
                }
                a.push(i);
            }
            while (!a.empty())
                a.pop();
            a.push(n-1);
            r1[n - 1] = n - 1;
            for (i = n - 2; i >= 0; i--){
                while (!a.empty() && l[i][j] <= l[a.top()][j])
                    a.pop();
                if (!a.empty()){
                    r1[i] = a.top() - 1;
                }else{
                    r1[i] = n - 1;
                }
                a.push(i);
            }
            while (!a.empty())
                a.pop();
            for (i = 0; i < n; i++){
                maxn = max(maxn, (max(r1[i] - l1[i] + 1, 1)) * l[i][j]);
                if (maxn == 9 && ff == false) {
                    jj = l1[i];
                    ff = true;
                }
            }
            for (i = 0; i < n; i++){
                l1[i] = 0;
                r1[i] = 0;
            }
        }
        return maxn;
    }
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值