85. 最大矩形
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] 输出: 6
第一步
我们把矩形横向定义为长,纵向定义为宽。
计算出每一点向右画,最远能画到多少。
换句话说,我们求出每一点宽为1的时候,长最大是多少。
例如对于样例中的输入,我们的计算结果是
1 0 1 0 0
1 0 3 2 1
5 4 3 2 1
1 0 0 1 0
再给一个样例
{{'1','1','1','1','1','1','1','1'},
{'1','1','1','1','1','1','1','0'},
{'1','1','1','1','1','1','1','0'},
{'1','1','1','1','1','0','0','0'},
{'0','1','1','1','1','0','0','0'}}
对于这个样例,我们的计算结果是
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
5 4 3 2 1 0 0 0
0 4 3 2 1 0 0 0
第二步
根据第一步计算结果计算最大矩形。
这里面有一个木桶原理,木桶能装多少水,取决于木桶的最短板。
对于每一个点,我们只考虑向右和向下的方向。第一步计算出了向右方向——最大的长。
接下来,我们开始向下扩展,每向下扩展一行,宽就要+1,长就会变成扩展的k行里面的最小值,面积就要动态变化,这样就可以找到每个点的面积最大值。
最后再找到全局最大值。
class Solution {
public int maximalRectangle(char[][] matrix) {
int m = matrix.length;
if (m == 0) {
return 0;
}
int n = matrix[0].length;
int[][] l = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '0') {
l[i][j] = 0;
continue;
}
int index = j + 1;
while (index < n && matrix[i][index] == '1') {
index++;
}
l[i][j] = index - j;
}
}
int maxS = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//遍历每个点,以该点为左上角
if (l[i][j] == 0) {
continue;
}
int s = l[i][j];
for (int k = 1; k < m - i && matrix[i + k][j] != '0'; k++) {
int minL = l[i][j];
// 找到 由i到i+k的最小值
for (int t = i + 1; t <= i + k; t++) {
if (minL >= l[t][j]) {
minL = l[t][j];
}
}
//当前点为左上角,面积所能达到的最大值
s = Math.max((k + 1) * minL, s);
}
maxS = Math.max(maxS, s);
}
}
return maxS;
}
}
public static void main(String[] args) {
Solution s = new Solution();
char[][] b = { { '1', '0', '1', '0', '0' },
{ '1', '0', '1', '1', '1' },
{ '1', '1', '1', '1', '1' },
{ '1', '0', '0', '1', '0' } };
char[][] b1 = { { '1', '1', '1', '1', '1', '1', '1', '1' },
{ '1', '1', '1', '1', '1', '1', '1', '0' },
{ '1', '1', '1', '1', '1', '1', '1', '0' },
{ '1', '1', '1', '1', '1', '0', '0', '0' },
{ '0', '1', '1', '1', '1', '0', '0', '0' } };
System.out.println(s.maximalRectangle(b1));
System.out.println(s.maximalRectangle(b));
}
测试结果:
21
6
66 / 66 个通过测试用例 |
状态: 通过 |
执行用时:42 ms |