85. Maximal Rectangle

用dp计算矩形面积

1题目理解

输入:char[][] matrix 是一个二维数组,值由0和1组成。
输出:一个矩形的面积,这个矩形只包含1。
例子:
Input:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
Output: 6

2分析

最开始没理解,直接想之前做过,从一个点向4个方向延伸,找最大值。写完,发现图形不是矩形。
开始思考,因为是矩形该怎么做。思路参考力扣

2.1 暴力搜索

枚举左上角(x1,y1)坐标和右下角(x2,y2)左边,计算面积。时间复杂度 O ( m 3 n 3 ) O(m^3n^3) O(m3n3)

2.2 动态规划

dp[i][j] = 在第i行,以j结尾的最长的包含1的子数组的长度。
d p [ i ] [ j ] = 0 , m a t r i x [ i ] [ j ] = ′ 0 ′ dp[i][j] = 0,matrix[i][j]='0' dp[i][j]=0,matrix[i][j]=0
d p [ i ] [ j ] = d p [ i ] [ j − 1 ] + 1 , m a t r i x [ i ] [ j ] = ′ 1 ′ dp[i][j] = dp[i][j-1]+1,matrix[i][j]='1' dp[i][j]=dp[i][j1]+1,matrix[i][j]=1

例如上面的例子 dp[1] = {1,0,1,2,3}
知道了每一行的宽度,从第i行开始,向上计算,找到最小的宽度,乘以高,就是矩形的面积。
这是一个动态规划dp的值只是返回值一部分的例子。

class Solution {
    private int maxSum;
    public int maximalRectangle(char[][] matrix) {
        if(matrix==null || matrix.length==0) return 0;
        int m = matrix.length;
        int n = matrix[0].length;
        int maxArea = 0;
        int[][]  dp = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='1'){
                    dp[i][j] = (j==0?1:dp[i][j-1]+1);
                    int minWidth = dp[i][j];
                    for(int upRow = i;upRow>=0;upRow--){
                        int height = i-upRow+1;
                        minWidth = Math.min(minWidth,dp[upRow][j]);
                        maxArea = Math.max(maxArea,minWidth*height);
                    }
                }
                
            }
            
        }
        return maxArea;
    }
    
  
}

3 相关题目

304 Range Sum Query 2D – Immutable 计算一个矩阵范围内的数字和

class NumMatrix {
    int[][] dp;
    public NumMatrix(int[][] matrix) {
        if(matrix == null || matrix.length == 0) return;
        int m  = matrix.length;
        int n = matrix[0].length;
        dp = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j = 0;j < n;j++){
                dp[i][j] = (i>0?dp[i-1][j]:0) 
                    + (j>0?dp[i][j-1]:0) 
                    - (i>0 && j>0? dp[i-1][j-1]:0) + matrix[i][j];
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        if(dp == null) return 0;
        return  dp[row2][col2] 
            - (row1>0?dp[row1-1][col2]:0) 
            - (col1 >0 ?dp[row2][col1-1]:0) 
            + (row1>0 && col1>0 ?dp[row1-1][col1-1]:0);
    }
}

221 Maximal Square 计算正方形的最大面积

class Solution {
    public int maximalSquare(char[][] matrix) {
        if(matrix==null || matrix.length==0) return 0;
        int m = matrix.length;
        int n = matrix[0].length;
        int maxSide = 0;
        int[][]  dp = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='1'){
                    if(i==0 || j==0){
                        dp[i][j] = 1;
                    }else{
                        dp[i][j] = Math.min(dp[i-1][j]
                                    ,Math.min(dp[i-1][j-1],dp[i][j-1]))+1;
                        
                    }
                    maxSide =  Math.max(maxSide,dp[i][j]);
                    
                }
                
            }
            
        }
        return maxSide * maxSide;
    }
}

1277 Count Square Submatrices with All Ones 数一数正方形的个数

class Solution {
    public int countSquares(int[][] matrix) {
        int count = 0;
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] dp = new int[m][n];
        for(int i = 0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j] == 1){
                    if(i==0 || j==0){
                        dp[i][j] =1;
                    }else{
                        dp[i][j] = Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                    }
                    count += dp[i][j];
                }
            }
        }
        return count;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值