算法: 最大矩形面积85. Maximal Rectangle

Posted AI架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法: 最大矩形面积85. Maximal Rectangle相关的知识,希望对你有一定的参考价值。

85. Maximal Rectangle

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

Example 1:

Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.

Example 2:

Input: matrix = [["0"]]
Output: 0

Example 3:

Input: matrix = [["1"]]
Output: 1

Constraints:

  • rows == matrix.length
  • cols == matrix[i].length
  • 1 <= row, cols <= 200
  • matrix[i][j] is '0' or '1'.

动态规划 针对当前位置求解面积,计算最大宽和高

DP 解决方案从第一行开始逐行进行。让第 i 行和第 j 列的最大矩形面积由 [right(i,j) - left(i,j)]*height(i,j) 计算。

所有 3 个变量 left、right 和 height 都可以由来自前一行的信息以及来自当前行的信息确定。所以它可以看作是一个DP解决方案。转移方程为:

  • left(i,j) = max(left(i-1,j), cur_left), cur_left 可以从当前行确定

  • right(i,j) = min(right(i-1,j), cur_right), cur_right 可以从当前行确定

  • height(i,j) = height(i-1,j) + 1,如果 matrix[i][j]=='1';

  • height(i,j) = 0, 如果 matrix[i][j]=='0'

代码如下。可以将循环组合以提高速度,但我将它们分开是为了使算法更清晰。

class Solution 
    public int maximalRectangle(char[][] matrix) 
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[] left = new int[cols];
        int[] right = new int[cols];
        int[] height = new int[cols];
        Arrays.fill(right, cols);
        int max = 0;
        for (int r = 0; r < rows; r++) 
            int curLeft = 0, curRight = cols;
            for (int c = 0; c < cols; c++) 
                height[c] = matrix[r][c] == '1' ? (height[c] + 1) : 0;
            
            for (int c = 0 ;c < cols; c++) 
                if (matrix[r][c] == '1') 
                    left[c] = Math.max(left[c], curLeft);
                 else 
                    left[c] = 0;
                    curLeft = c + 1;
                
            
            for (int c = cols - 1; c >= 0; c--) 
                if (matrix[r][c] == '1') 
                    right[c] = Math.min(right[c], curRight);
                 else 
                    right[c] = cols;
                    curRight = c;
                
            
            for (int c = 0; c < cols; c++) 
                max = Math.max(max, (right[c] - left[c]) * height[c]);
            
        
        
        return max;
    

如果觉得这个算法不好理解,可以试试这个例子:

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

从第0行到第2行的向量“左”和“右”如下

第 0 行:dp[0][*]

h: 0 0 0 1 0 0 0
l: 0 0 0 3 0 0 0
r: 7 7 7 4 7 7 7

第 1 行:dp[1][*]

h: 0 0 1 2 1 0 0
l: 0 0 2 3 2 0 0
r: 7 7 5 4 5 7 7 

第 2 行:dp[2][*]

h: 0 1 2 3 2 1 0
l: 0 1 2 3 2 1 0
r: 7 6 5 4 5 6 7

向量“left”正在计算左边界。以 (i,j)=(1,3) 为例。在当前行 1 上,左边界位于 j=2。但是,因为 matrix[1][3] 是 1,所以还需要考虑上一行的左边界,即 3。所以 (1,3) 处的真正左边界是 3。

每一行都计算最大max,比如这里以第三行举例,dp[2][*]
公式为 Math.max(max, (r - l) * h)

0: max(0, (7 - 0)*0) = 0
1: max(0, (6 - 1)*1) = 5
2: max(5, (5 - 2)*2) = max(5, 6) = 6
3: max(6, (4 - 3)*3) = max(6, 3) = 6
4: max(6, (5 - 2)*2) = max(6, 6) = 6
5: max(6, (6 - 1)*1) = max(6, 5) = 6
6: max(6, (7 - 0)*0) = max(6, 0) = 6

我希望这个额外的解释能让事情更清楚。

参考

https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution

以上是关于算法: 最大矩形面积85. Maximal Rectangle的主要内容,如果未能解决你的问题,请参考以下文章

85. Maximal Rectangle 由1拼出的最大矩形

leetcode 85. Maximal Rectangle

[leetcode]85. Maximal Rectangle 最大矩形

最大的矩形面积 Maximal Rectangle

84. Largest Rectangle in Histogram *HARD* 柱状图求最大面积 85. Maximal Rectangle *HARD*

maximal-rectangle——找出最大矩形的面积