85. Maximal Rectangle

本文详细解析了如何使用动态规划解决二维矩阵中寻找由‘1’组成的最大矩形面积问题,通过高度、左边界和右边界三个数组进行迭代计算,最终得出最大矩形面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

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

Example:

Input:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
Output: 6

Problem URL


Solution

给一个二维char数组,找到由‘1’组成的最大的正方形面积。

Using dynamic programming to solve this problem. We use three arrays left, right and height to perfrom dp row by row.

height[] document the height of this position, if it is ‘1’ height[j]++.

left[] stores the left consecutive ‘1’ start position(inclusive), using curLeft to denote this iteration’s ‘1’'s position, compare with last row, find max one(because it is compare with 0, if last row does not have 1). or we should set it to initial value 0 and move curLeft forward.

right[] stores the right consecutive ‘1’ start position(exclusive), using curRight to denote this iteration’s ‘1’'s position, compare with last row, find min one(because it is compare with n, if last row does not have 1). Or we should set it to initial value n and curRIght = n;

After that, compute area one by one and compare with res.

Code
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return 0;
        }
        int m = matrix.length, n = matrix[0].length;
        int[] left = new int[n], right = new int[n], height = new int[n];
        Arrays.fill(right, n);
        int res = 0;
        for (int i = 0; i < m; i++){
            int curLeft = 0, curRight = n;
            for (int j = 0; j < n; j++){
                if (matrix[i][j] == '1'){
                    height[j]++;
                }
                else{
                    height[j] = 0;
                }
            }
            for (int j = 0; j < n; j++){
                if (matrix[i][j] == '1'){
                    left[j] = Math.max(left[j], curLeft);
                }
                else{
                    left[j] = 0;
                    curLeft = j + 1;
                }
            }
            for (int j = n - 1; j >= 0; j--){
                if (matrix[i][j] == '1'){
                    right[j] = Math.min(right[j], curRight);
                }
                else{
                    right[j] = n;
                    curRight = j;
                }
            }
            for (int j = 0; j < n; j++){
                res = Math.max(res, (right[j] - left[j]) * height[j]);
            }
        }
        return res;
    }
}

Time Complexity: O(mn)
Space Complexity: O(n)


Review

We could speed up by using two iteration.

class Solution {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return 0;
        }
        int m = matrix.length, n = matrix[0].length;
        int[] left = new int[n], right = new int[n], height = new int[n];
        Arrays.fill(right, n);
        int res = 0;
        for (int i = 0; i < m; i++){
            int curLeft = 0, curRight = n;
            for (int j = 0; j < n; j++){
                if (matrix[i][j] == '1'){
                    height[j]++;                    
                    left[j] = Math.max(left[j], curLeft);
                }
                else{
                    height[j] = 0;
                    
                    left[j] = 0;
                    curLeft = j + 1;
                }
                int k = n - 1 - j;
                if (matrix[i][k] == '1'){
                    right[k] = Math.min(right[k], curRight);
                }
                else{
                    right[k] = n;
                    curRight = k;
                }
            }

            for (int j = 0; j < n; j++){
                res = Math.max(res, (right[j] - left[j]) * height[j]);
            }
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值