leetcode-Maximal Rectangle

22 篇文章 0 订阅
22 篇文章 0 订阅

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

题意:给出一个矩形,里面填充'0'和'1',找出完全由'1'组成的最大子矩形的面积。

分析:我是用dp做这道题的。用row[i][j]和col[i][j]分别记录以点(i,j)为右下角的全1子矩形的行数和列数。用right[i][j]和down[i][j]记录以(i,j)为结尾的从左到右连续1个数、从上到下连续1个数。

依次遍历每个点(i,j),考虑点(i-1,j)和(i,j-1)。

对于点(i-1,j),考虑(row[i-1][j]+1)*col[i-1][j]是否小于单行连续1个数right[i][j],若小于,记录以(i,j)为右下角的最大矩形为这个单行连1;否则,记录为(i-1,j)对应矩形加当前行,列数为min(col[i-1][j],right[i][j])。

对于点(i-1,j),考虑row[i][j-1]*(col[i][j-1]+1)是否小于单列连续1个数down[i][j],若小于,记录以(i,j)为右下角的最大矩形为这个单列连1;否则,记录为(i,j-1)对应矩形加当前列,行数为min(row[i][j-1],down[i][j])。

选上述两个结果的较大矩形,作为(i,j)的结果。

记录所有点中的最大矩形面积,即为结果。

代码:

class Solution {
public:
    int maximalRectangle(vector<vector<char> > &matrix) {
        
        int n = matrix.size();
        if(n==0) return 0;
        int m = matrix[0].size();
        if(m==0) return 0;
        
        int **row = new int*[n+1];
        int **col = new int*[n+1];
        int **right = new int*[n+1];
        int **down = new int*[n+1];
        for(int i=0; i<=n; i++)
        {
            row[i] = new int[m+1];
            col[i] = new int[m+1];
            right[i] = new int[m+1];
            down[i] = new int[m+1];
        
            memset(row[i],0,sizeof(int)*(m+1));
            memset(col[i],0,sizeof(int)*(m+1));
            memset(right[i],0,sizeof(int)*(m+1));
            memset(down[i],0,sizeof(int)*(m+1));
        }
        
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(matrix[i][j]=='0') right[i+1][j+1]=0;
                else right[i+1][j+1]=right[i+1][j]+1;
            }
        }
        
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(matrix[j][i]=='0') down[j+1][i+1]=0;
                else down[j+1][i+1]=down[j][i+1]+1;
            }
        }
        int ans = 0;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(matrix[i-1][j-1]=='1')
                {
                    row[i][j]=1;
                    col[i][j]=1;
                    
                    int r1,c1,r2,c2;
                    if(right[i][j]>(row[i-1][j]+1)*col[i-1][j])
                    {
                        r1 = 1;
                        c1 = right[i][j];
                    }
                    else
                    {
                        r1 = row[i-1][j]+1;
                        c1 = min(col[i-1][j],right[i][j]);
                    }
                    if(down[i][j]>row[i][j-1]*(col[i][j-1]+1))
                    {
                        r2 = down[i][j];
                        c2 = 1;
                    }
                    else
                    {
                        r2 = min(row[i][j-1],down[i][j]);
                        c2 = col[i][j-1]+1;
                    }
                    if(r1*c1>r2*c2)
                    {
                        row[i][j] = r1;
                        col[i][j] = c1;
                    }
                    else
                    {
                        row[i][j] = r2;
                        col[i][j] = c2;
                    }
                    if(row[i][j]*col[i][j]>ans)
                        ans = row[i][j]*col[i][j];
                }
            }
        }
        
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值