题目:Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
思路:DP
按行扫描,维护三个数组,height、left、right,记录包含当前元素matrix[i][j]所在列‘1’的高度(height),以及左边界(left)和右边界(right)。并记录最大的面积:(right-left)*height。
左右边界定位的时候,要考虑上一行的left right情况。
代码:
public int maximalRectangle(char[][] matrix) {
if(matrix==null||matrix.length==0)
return 0;
int max=0;
int m = matrix.length;
int n = matrix[0].length;
int[]height = new int[n];
int[]left = new int[n];
int[]right = new int[n];
//init right
for(int j=0;j<n;j++)
<span style="white-space:pre"> </span>right[j]=n;
//scan each row of matrix
for(int i=0;i<m;i++){
//get height
for(int j=0;j<n;j++){
if(matrix[i][j]=='1')
height[j]++;
else
height[j]=0;
}
//get left
int cur_left=0;
for(int j=0;j<n;j++){
if(matrix[i][j]=='1'){
left[j]=Math.max(left[j], cur_left);
}else{
left[j]=0;
cur_left=j+1;
}
}
//get right
int cur_right=n;
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;
}
}
//get current max area
for(int j=0;j<n;j++)
max = Math.max(max, (right[j]-left[j])*height[j]);
}
return max;
}
思路2:可以借鉴http://blog.csdn.net/u013127687/article/details/50877436
按行读取,每一行的处理思路和Largest Rectangle in Histogram一样,用stack。
leetcode上的解法:
public class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix==null||matrix.length==0||matrix[0].length==0)
return 0;
int cLen = matrix[0].length; // column length
int rLen = matrix.length; // row length
// height array
int[] h = new int[cLen+1];
h[cLen]=0;
int max = 0;
for (int row=0;row<rLen;row++) {
Stack<Integer> s = new Stack<Integer>();
for (int i=0;i<cLen+1;i++) {
if (i<cLen)
if(matrix[row][i]=='1')
h[i]+=1;
else h[i]=0;
if (s.isEmpty()||h[s.peek()]<=h[i])
s.push(i);
else {
while(!s.isEmpty()&&h[i]<h[s.peek()]){
int top = s.pop();
int area = h[top]*(s.isEmpty()?i:(i-s.peek()-1));
if (area>max)
max = area;
}
s.push(i);
}
}
}
return max;
}
}