public class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix == null) {
throw new IllegalArgumentException("");
}
if (matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int[][] heights = new int[matrix.length][matrix[0].length];
for (int i = 0; i < heights.length; i++) {
for (int j = 0; j < heights[0].length; j++) {
if (i == 0) {
heights[i][j] = matrix[i][j] == '1' ? 1 : 0;
} else {
heights[i][j] = matrix[i][j] == '1' ? 1 : 0;
if (heights[i][j] != 0) {
heights[i][j] = heights[i][j] + heights[i - 1][j];
}
}
}
}
int maxArea = 0;
int row = heights.length, column = heights[0].length;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (stack.isEmpty()) {
stack.push(j);
} else {
while (!stack.isEmpty() && heights[i][j] < heights[i][stack.peek()]) {
int last_height = heights[i][stack.pop()];
if (!stack.isEmpty()) {
maxArea = Math.max(maxArea, (j - 1 - stack.peek())*last_height);
} else {
maxArea = Math.max(maxArea, (j)*last_height);
}
}
stack.push(j);
}
}
while (!stack.isEmpty()) {
int last_height = heights[i][stack.pop()];
if (!stack.isEmpty()) {
maxArea = Math.max(maxArea, (column - 1 - stack.peek())*last_height);
} else {
maxArea = Math.max(maxArea, (column)*last_height);
}
}
}
return maxArea;
}
}