题目描述:
难度:困难 相关标签:栈、数组、动态规划、矩阵、单调栈 给定一个仅包含0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:6 解释:最大矩形如上图所示。 示例 2: 输入:matrix = [] 输出:0 示例 3: 输入:matrix = [["0"]] 输出:0 示例 4: 输入:matrix = [["1"]] 输出:1 示例 5: 输入:matrix = [["0","0"]] 输出:0 提示: rows == matrix.length cols == matrix[0].length 1 <= row, cols <= 200 matrix[i][j] 为 '0' 或 '1'
解题:
1. 我们首先计算出矩阵的每个元素的左边连续 1 的数量,使用二维数组 left 记录,其中 left[i][j] 为矩阵第 i 行第 j 列元素的左边连续 1 的数量。
2. 对于矩阵中任意一个点,我们枚举 以该点作为右下角 的全 1 矩形。
class Solution {
//自己写的(优化柱状暴力)
public int maximalRectangle(char[][] matrix) {
if( matrix == null )
return 0;
int x = matrix.length, y = matrix[ 0 ].length;
//我们首先计算出矩阵的每个元素的左边连续 1 的数量,使用二维数组 left 记录,其中 left[i][j] 为矩阵第 i 行第 j 列元素的左边连续 1 的数量。
int[][] left = new int[ x ][ y ];
for ( int i = 0; i < x; i ++ ) {
for ( int j = 0; j < y; j ++ ) {
if( matrix[ i ][ j ] == '1' ) {
left[ i ][ j ] = ( j == 0 ? 0 : left[ i ][ j - 1 ] ) + 1;
}
System.out.print( left[ i ][ j ] + " " );
}
System.out.println();
}
//对于矩阵中任意一个点,我们枚举 以该点作为右下角 的全 1 矩形。
int max = 0;
int[][] dp= new int[ x ][ y ];
for ( int i = 0; i < x; i ++ ) {
for ( int j = 0; j < y; j ++ ) {
if( left[ i ][ j ] != 0 ) {
int width = left[ i ][ j ];
if ( max == 0 )
max = width * 1;
int high = 0, min = width;
for( int a = i; a >= 0; a -- ) {
high ++;
min = left[ a ][ j ] <= min ? left[ a ][ j ] : min;
if ( left[ a ][ j ] == 0 )
break;
if ( left[ a ][ j ] >= width ) {
if ( width <= min )
max = ( width * high ) >= max ? width * high : max;
else max = ( min * high ) >= max ? min * high : max;
} else if ( left[ a ][ j ] < width ) {
if(left[ a ][ j ] <= min )
max = left[ a ][ j ] * high >= max ? left[ a ][ j ] * high : max;
else max = ( min * high ) >= max ? min * high : max;
}
}
}
}
}
return max;
}
}