*LeetCode-Maximal Rectangle

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;
    }
}


你可能感兴趣的:(*LeetCode-Maximal Rectangle)