找短板1:柱状图中的最大矩阵面积

博客探讨了一维柱状图中最大矩阵面积的问题,通过转换成短板问题,可以在O(n)时间内求解。同时,文章还讨论了如何将这种方法应用于二值矩阵中找元素全为1的面积最大矩阵,虽然复杂度提升到O(n^2),但依然提供了有效的解决方案。
摘要由CSDN通过智能技术生成

柱状图中的最大矩阵面积

有一类题目,输入往往是一维数组,求解最值。表面看是一个普通的优化问题,直接想到用动态规划求解。但是在寻找最优子结构的时候,我们发现这个优化问题的最优子结构并不是那么清晰。这个时候我们可以看看这个问题可否转化为计算每个位置的短板。一旦能转化为短板问题,问题往往就能在 o(n) 时间解决。

题目

给定一个一维数组,描述一个柱状图中各个柱子的高度。矩阵宽度由数组下标衡量。求柱状图中能由柱子完全填充的最大矩形面积。

解析

短板:当前柱子的高度。因为当前柱子的高度决定了矩形面积的大小。
所以只要计算出每个位置以当前柱高height.at(i)为矩形长度的矩形面积,并更新最大面积即可。
如何计算每个位置以当前柱高为矩形长度的矩形的宽度呢?只需要从左到右扫描一遍,找到左边距离当前位置最近且高度刚好小于当前柱高的位置lmin.at(i);从右到左扫描一遍,找到右边距离当前位置最近且高度刚好小于当前柱高的位置rmin.at(i)。则当前矩形面积为 height.at(i)(rmin.at(i)lmin.at(i)1)

代码

    int largestRectangleArea(vector<int>& height) {
        int len = height.size();
        vector<int> lmin(len+1, -1);
        vector<int> rmin(len+1, len);
        for(int i=1; i<len; i++)
        {   
            if( height.at(i) > height.at(i-1) ) lmin.at(i) = i-1;
            else
            {
                int j = i-1;
                while( j>=0 && height.at(j) >= height.at(i) ) j = lmin.at(j);
                lmin.at(i) = j;
            }
        }
        for(int i=len-2; i>=0; i--)
        {
            if( height.at(i) > height.at(i+1) ) rmin.at(i) = i+1;
            else
            {
                int j = i+1;
                while( j<=len-1 && height.at(j) >= height.at(i) ) j = rmin.at(j);
                rmin.at(i) = j;
            }
        }
        int ret = 0;
        for(int i=0; i<len; i++)
            ret = max(ret, height.at(i) * (rmin.at(i) - lmin.at(i) - 1) );
        return ret;
    }

复杂度分析

该问题时间复杂度 o(n) ,空间复杂度 o(1)

二值矩阵中找元素全为1的面积最大矩阵

这道题可以调用上一道题的代码。关键在于如何转换。

问题分析

    0 0 0 1
    1 0 1 1
    1 1 1 1
    1 1 1 1

先看最简单的情况。假如输入矩阵如上。直观上看,最优值应该是4*2=8。从上往下一行一行地看。在只有第一行时,最优值为1;前两行时,我们应该在两行的最优值中选最优值(最大值),也就是2。第二行的最优值计算时,我们会从上往下累计当前列连续的1的个数h,然后左右延伸,看以当前h为长的最大矩形。这个时候,我们发现对于每一行,我们只需要将h向量计算好,作为“柱状图中最大矩阵面积”的输入,求得最大值。然后更新全局最大值即可。

代码

    int maximalRectangle(vector<vector<char>>& matrix) {
        int m = matrix.size();
        if(m==0) return 0;
        int n = matrix.at(0).size();
        vector< vector<int> > buf( m, vector<int>(n, 0) );
        int ret = 0;
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(i==0) buf.at(i).at(j) = matrix.at(i).at(j) - '0';
                else buf.at(i).at(j) = (matrix.at(i).at(j)=='1') ? (buf.at(i-1).at(j)+1) : 0;
            }
            ret = max(ret, largestRectangleArea(buf.at(i)) );
        }
        return ret;
    }

复杂度分析

该问题时间复杂度 o(n2) ,空间复杂度 o(n2)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值