DP!!!!!!
分别用和宽度相等的三个数组 记录每一行这个位置所处的字符所在的rect的左右边界和高度
left(i,j) = max(left(i-1,j), curleft), curleft can be determined from the current row
right(i,j) = min(right(i-1,j), curright), curright can be determined from the current row
height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1';
height(i,j) = 0, if matrix[i][j]=='0'
这里虽然用了left( i, j )的表示方式 但是实际只需要用一位数组 然后每一行重复利用就可以了注意重复利用时候的index 同时注意right 更新的时候是从右向左
然后就是cur_left cur_right的初始化,left都初始化成0 right都初始化成n 主要是取min max的时候不影响 假如这个位置是‘0’就set成初始值 不用担心此时left = 0,right = n 因为height = 0
然后每一行都要把area扫一遍 update max
public class Solution { public int maximalRectangle(char[][] matrix) { if ( matrix == null || matrix.length == 0) return 0; int m = matrix.length; int n = matrix[0].length; int [] heights = new int [ n ]; int [] left = new int [ n ]; int [] right = new int [ n ]; Arrays.fill ( right, n ); int res = 0; for ( int i = 0; i < m; i ++ ){ int cur_left = 0; int cur_right = n; for ( int j = 0; j < n; j ++ ){ if ( matrix[ i ][ j ] == '1' ){ heights[ j ] = heights [ j ] + 1; left [ j ] = Math.max ( left [ j ], cur_left ); } else{ heights[ j ] = 0; left[ j ] = 0; cur_left = j + 1; } } for ( int j = n - 1; j >= 0; j -- ){ if ( matrix[ i ][ j ] == '1' ){ right [ j ] = Math.min( right [ j ], cur_right ); } else{ right [ j ] = n; cur_right = j; } } for ( int j = 0; j < n; j ++ ){ res = Math.max ( res, (right[j] - left[ j ]) * heights[ j ] ); } } return res; } }