85. Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing
only 1's and return its area.
Example:
Input:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
Output: 6
- MonotonicStack
public int maximalRectangle(char[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
int[] h = new int[matrix[0].length+1];
int result = 0;
for(int i = 0; i < matrix.length; i++) {
if(i == 0) {
for(int j = 0; j < matrix[0].length; j++)
h[j] = matrix[i][j] == '1' ? 1 : 0;
} else {
for(int j = 0; j < matrix[0].length; j++)
h[j] = matrix[i][j] == '1' ? h[j] + 1 : 0;
}
result = Math.max(result, largestRectangleArea(h));
}
return result;
}
public int largestRectangleArea(int[] h) {
ArrayDeque<Integer> stack = new ArrayDeque<>();
stack.push(-1);
int result = 0;
for(int i = 0; i < h.length; i++) {
while(stack.peek() != -1 && h[stack.peek()] > h[i]) {
int height = h[stack.pop()];
result = Math.max(result, height * (i - 1 - stack.peek()));
}
stack.push(i);
}
return result;
}
- DP row by row, N^2 * M
public int maximalRectangleAccumulateRows(char[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0) return 0;
int result = Integer.MIN_VALUE;
int[] temp = new int[matrix[0].length];
for(int i = 0; i < matrix.length; i++) {
for(int j = i; j < matrix.length; j++) {
if(j == i) {
for(int k = 0; k < temp.length; k++) temp[k] = matrix[j][k] - '0';
}
else {
for(int k = 0; k < matrix[0].length; k++) {
if(matrix[j][k] == '1' && temp[k] > 0) temp[k] += 1;
else temp[k] = 0;
}
}
int sum = 0;
for(int k = 0; k < temp.length; k++) {
if(k == 0 || temp[k] != temp[k-1]) sum = temp[k];
else sum += temp[k];
result = Math.max(sum, result);
}
}
}
return result;
}
or
public int maximalRectangleReduceDimension(char[][] matrix) {
if(matrix==null || matrix.length == 0 || matrix[0] == null || matrix[0].length==0) return 0;
int n = matrix.length, m = matrix[0].length;
int ans = 0;
char[] buffer = new char[m];
Arrays.fill(buffer, '1');
for(int i = 0; i < n; i++) {
for(int j = i; j < n; j++) {
int cols = 0;
for(int k = 0; k < m; k++) {
buffer[k] = buffer[k] == '1' && matrix[j][k] == '1' ? '1' : '0';
}
for(int k = 0; k < m; k++) {
if(buffer[k] == '0') {
cols = 0;
} else {
cols++;
}
ans = Math.max(ans, (j-i+1)*cols);
}
}
Arrays.fill(buffer,'1');
}
return ans;
}