Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
分析:
之所以先写68,是因为这道题是以68题为子问题的,关键就是怎么构造直方图了。
对每一行都建直方图,
如果第 i 行第 j 列元素为1,则第 i 行该位置高度就是第 i-1 行该位置高度+1,即 height[i][j] = height[i-1][j] + 1;
如果此位置元素为0,则此行该位置的高度就是0,因为已经没有和上一行的1连续了,高度要重新算起了。
public class Solution {
public int maximalRectangle(char[][] matrix) {
int m = matrix.length;
int n = m == 0 ? 0 : matrix[0].length;
//这里用了一个小技巧,就是让每一行的直方图最后一个元素是0
//这样的好处是遍历到最后栈一定是空的,避免了最后在弹栈的多余代码
int[][] height = new int[m][n+1];
int maxArea = 0;
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(matrix[i][j] == '0'){
height[i][j] = 0;
}else{
height[i][j] = i==0 ? 1:height[i-1][j]+1;
}
}
}
for(int i=0; i<m; i++){
int area = maxAreaInHist(height[i]);
if(area > maxArea)
maxArea = area;
}
return maxArea;
}
private int maxAreaInHist(int[] height){
Stack<Integer> st = new Stack<Integer>();
int i=0;
int max = 0;
while(i < height.length){
if(st.isEmpty() || height[st.peek()] <= height[i]){
st.push(i);
i++;
}else{
int t = st.pop();
max = Math.max(max, height[t]*(st.isEmpty() ? i : i-st.peek()-1));
}
}
return max;
}
}