Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
最土的做法无疑就是遍历矩阵中的所有矩形,时间复杂度为O(n^2 * m ^2)不用试估计也会超时了,看了讨论组里面有位大神提供了这样的思路:
This question is similar as [
Largest Rectangle in Histogram]:
You can maintain a row length of Integer array H recorded its height of '1's, and scan and update row by row to find out the largest rectangle of each row.
You can maintain a row length of Integer array H recorded its height of '1's, and scan and update row by row to find out the largest rectangle of each row.
什么意思呢?给大家用图例展示一下:想看详细步骤的可以戳这里:
虽然上图画错了,但是还是表达出了大神的意思:
对原矩阵matrix的每一行生成并维护一个int[]数组。
这个数组表示以该行为底线,与上面所有行组成的高度数组,比如第三行是0 1 1 1,但是matrix[1][3] 也是1,因此最有一个元素的高度应该是2(图中只花了1个高度)
思考一下:第2行第三个元素是0,但是它上面是1,为什么高度和是0而不是1呢?(想不通面壁去)
因此我们可以由matrix的每一行生成一个int[]高度数组,是不是回到了[Largest Rectangle in Histogram]?
因此我们要做的就是对每一行生成一个int[]数组。再对每个int[]数组调用Largest Rectangle in Histogram中的方法即可。
public int maximalRectangle(char[][] matrix) {
if(matrix == null || matrix.length == 0) return 0;
int rowCount = matrix.length;
int columnCount = matrix[0].length;
int[][] rectangle = new int[rowCount][columnCount];
for(int i = 0; i < rowCount; i++){
for(int j = 0; j < columnCount;j++){
if(i == 0){
rectangle[i][j] = matrix[i][j] == '1' ? 1 : 0;
}else{
rectangle[i][j] = matrix[i][j] == '1' ? 1 + rectangle[i - 1][j] : 0;
}
}
}
int maxArea = 0;
for(int i = 0; i < rowCount; i++){
int tem = getLargestRectangle(rectangle[i]);
maxArea = tem > maxArea ? tem : maxArea;
}
return maxArea;
}
下面是Largest Rectangle in Histogram中的源代码,一模一样,而且两道题在leetcode中的位置也是挨着的,算是提示吗?
private int getLargestRectangle(int[] height){
int[] copy = new int[height.length + 1];
copy = Arrays.copyOf(height, height.length + 1);
Stack<Integer> stack = new Stack<Integer>();
int maxArea = 0;
int i = 0;
while(i < copy.length){
if(stack.isEmpty() || copy[stack.peek()] < copy[i]){
stack.push(i++);
}else{
int num = stack.pop();
maxArea = Math.max(maxArea,copy[num] * (stack.isEmpty() ? i : i - stack.peek() - 1));
}
}
return maxArea;
}