2121 */
2222public class MaximalRectangle {
2323
24- /**
25- * DP.
26- * Three matrices: left, right, and height.
27- * Height is number of continuous 1's that end at j.
28- * Left is the left boundary of this height. The actual value is an index.
29- * Right is the right boundary of this right. The actual value is index + 1.
30- * The rectangle area of this height at row i and column j is: [right(i,j) - left(i,j)] * height(i,j).
31- * <p>
32- * Recurrence relations:
33- * left(i,j) = max(left(i-1,j), leftBound)
34- * leftBound is the leftmost 1 of this height at current row.
35- * All left boundaries are initialized as 0, which is the leftmost possible.
36- * <p>
37- * right(i,j) = min(right(i-1,j), rightBound)
38- * rightBound is the rightmost 1 of this height at current row + 1.
39- * All right boundaries are initialized as n, which is the rightmost possible.
40- * <p>
41- * height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1'.
42- * height(i,j) = 0, if matrix[i][j]=='0'.
43- * <p>
44- * Implementation:
45- * Initialize left array and height as all zeroes, right array as the column length.
46- * For each row in the matrix, update height, left, right arrays.
47- * Then compute the area and record the maximum.
48- * Stop when all grids are done.
49- * https://discuss.leetcode.com/topic/6650/share-my-dp-solution
50- * <p>
51- * Note that the rectangle area we get is not the maximum at each grid, rather, it's the area of the rectangle of
52- * the maximum possible height.
53- * Why does that covers the maximum rectangle?
54- * Because:
55- * If the max rectangle has only 1 column, the bottom grid will have the max area.
56- * If the max rectangle has > 1 columns, the bottom row will have the max area.
57- */
58- public int maximalRectangle (char [][] matrix ) {
59- int m = matrix .length ;
60- int n = matrix [0 ].length ;
61- int [] left = new int [n ];
62- int [] right = new int [n ];
63- int [] height = new int [n ];
64- // Arrays.fill(left, 0);
65- Arrays .fill (right , n );
66- // Arrays.fill(height, 0);
67- int max = 0 ;
68- for (int i = 0 ; i < m ; i ++) {
69- // Compute height (can do this from either side).
70- for (int j = 0 ; j < n ; j ++) {
71- if (matrix [i ][j ] == '1' ) {
72- height [j ]++;
73- } else {
74- height [j ] = 0 ;
75- }
76- }
77- // Compute left boundaries (must from left to right).
78- int leftBound = 0 ; // Index of leftmost 1 of current row.
79- for (int j = 0 ; j < n ; j ++) {
80- if (matrix [i ][j ] == '1' ) {
81- left [j ] = Math .max (left [j ], leftBound );
82- } else {
83- left [j ] = 0 ;
84- leftBound = j + 1 ;
85- }
86- }
87- // Compute right boundaries (must from right to left).
88- int rightBound = n ; // Index + 1 of rightmost 1 of current row.
89- for (int j = n - 1 ; j >= 0 ; j --) {
90- if (matrix [i ][j ] == '1' ) {
91- right [j ] = Math .min (right [j ], rightBound );
92- } else {
93- right [j ] = n ; // Like reset. Make sure right[j] >= curRight.
94- rightBound = j ;
95- }
96- }
97- // Compute the area of rectangle (can do this from either side).
98- for (int j = 0 ; j < n ; j ++) {
99- max = Math .max (max , (right [j ] - left [j ]) * height [j ]);
100- }
24+ /**
25+ * DP.
26+ * Three matrices: left, right, and height.
27+ * Height is number of continuous 1's that end at j.
28+ * Left is the left boundary of this height. The actual value is an index.
29+ * Right is the right boundary of this right. The actual value is index + 1.
30+ * The rectangle area of this height at row i and column j is: [right(i,j) - left(i,j)] * height(i,j).
31+ * <p>
32+ * Recurrence relations:
33+ * left(i,j) = max(left(i-1,j), leftBound)
34+ * leftBound is the leftmost 1 of this height at current row.
35+ * All left boundaries are initialized as 0, which is the leftmost possible.
36+ * <p>
37+ * right(i,j) = min(right(i-1,j), rightBound)
38+ * rightBound is the rightmost 1 of this height at current row + 1.
39+ * All right boundaries are initialized as n, which is the rightmost possible.
40+ * <p>
41+ * height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1'.
42+ * height(i,j) = 0, if matrix[i][j]=='0'.
43+ * <p>
44+ * Implementation:
45+ * Initialize left array and height as all zeroes, right array as the column length.
46+ * For each row in the matrix, update height, left, right arrays.
47+ * Then compute the area and record the maximum.
48+ * Stop when all grids are done.
49+ * https://discuss.leetcode.com/topic/6650/share-my-dp-solution
50+ * <p>
51+ * Note that the rectangle area we get is not the maximum at each grid, rather, it's the area of the rectangle of
52+ * the maximum possible height.
53+ * Why does that covers the maximum rectangle?
54+ * Because:
55+ * If the max rectangle has only 1 column, the bottom grid will have the max area.
56+ * If the max rectangle has > 1 columns, the bottom row will have the max area.
57+ */
58+ public int maximalRectangle (char [][] matrix ) {
59+ int m = matrix .length ;
60+ int n = matrix [0 ].length ;
61+ int [] left = new int [n ];
62+ int [] right = new int [n ];
63+ int [] height = new int [n ];
64+ // Arrays.fill(left, 0);
65+ Arrays .fill (right , n );
66+ // Arrays.fill(height, 0);
67+ int max = 0 ;
68+ for (int i = 0 ; i < m ; i ++) {
69+ // Compute height (can do this from either side).
70+ for (int j = 0 ; j < n ; j ++) {
71+ if (matrix [i ][j ] == '1' ) {
72+ height [j ]++;
73+ } else {
74+ height [j ] = 0 ;
10175 }
102- return max ;
76+ }
77+ // Compute left boundaries (must from left to right).
78+ int leftBound = 0 ; // Index of leftmost 1 of current row.
79+ for (int j = 0 ; j < n ; j ++) {
80+ if (matrix [i ][j ] == '1' ) {
81+ left [j ] = Math .max (left [j ], leftBound );
82+ } else {
83+ left [j ] = 0 ;
84+ leftBound = j + 1 ;
85+ }
86+ }
87+ // Compute right boundaries (must from right to left).
88+ int rightBound = n ; // Index + 1 of rightmost 1 of current row.
89+ for (int j = n - 1 ; j >= 0 ; j --) {
90+ if (matrix [i ][j ] == '1' ) {
91+ right [j ] = Math .min (right [j ], rightBound );
92+ } else {
93+ right [j ] = n ; // Like reset. Make sure right[j] >= curRight.
94+ rightBound = j ;
95+ }
96+ }
97+ // Compute the area of rectangle (can do this from either side).
98+ for (int j = 0 ; j < n ; j ++) {
99+ max = Math .max (max , (right [j ] - left [j ]) * height [j ]);
100+ }
103101 }
102+ return max ;
103+ }
104104}
0 commit comments