这是非常难理解的两道题,其中第二题要以第一题为基础,否则非常难获得思路。这两题也耗费了大量的时间来研究,消耗了大量脑细胞。
Largest Rectangle in Histogram
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
For example,
Given height = [2,1,5,6,2,3]
,
return 10
.
依次遍历直方图的每一个元素:如果该元素比栈中的栈顶元素大,则压入栈中。如果比栈顶的元素小,则依次弹出栈顶元素,直到此时的栈顶元素比该元素小为止,并且将该元素压入栈中。同时,在出栈的时候,没弹出一个元素,计算此元素能够围成的最大矩形面积,保存在max中。
采用这种方法,遍历完所有元素之后,max的值则为需要所求最大矩形面积。
public class Solution {
public int largestRectangleArea(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
int max = 0;
for (int i = 0; i <= height.length; i++) {
int curt = (i == height.length) ? -1 : height[i];
while (!stack.isEmpty() && curt <= height[stack.peek()]) {
int h = height[stack.pop()];
int w = stack.isEmpty() ? i : i - stack.peek() - 1;
max = Math.max(max, h * w);
}
stack.push(i);
}
return max;
}
}
Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
在没有看到上面那题的时候,我先遇到了这题,一时之间根本没有思路,网上找了很多解题代码,也很难理解。所以我觉得在解此题时,应该充分理解了上一题。我们可以在上一题的基础上,来解这道题。
求矩阵中全部为“1”的最大子矩阵面积。解题思路:根据行遍历此矩阵,把每一行当作是一个直方图。这里又涉及到了矩阵和直方图的转化问题。
首先对于每一列,如果元素对应的上一行元素也为1,则该元素对应直方图高度为1+1,如果上一行的上一行依然为1,则对应高度为1+1+1,以此类推。这样即实现了矩阵每一行对应于一个直方图。
例如:
最后即可遍历矩阵中的每一行,按照上题求直方图最大子矩阵面积的方法,完成此题。
public class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix==null||matrix.length==0)
return 0;
if (matrix[0]==null||matrix[0].length==0)
return 0;
int[] record = new int[matrix[0].length];
Arrays.fill(record,0);
int result = 0;
Stack<Integer> index = new Stack<Integer>();
index.push(-1);
for (int i=0;i<matrix.length;i++){
for (int j=0;j<matrix[0].length;j++){
if (matrix[i][j]=='1')
record[j]+=1;
else
record[j]=0;
while(index.peek()>-1)
if (record[index.peek()]>record[j]){
int top=index.pop();
result=Math.max(result,record[top]*(j-index.peek()-1));
}
else break;
index.push(j);
}
while(index.peek()>-1){
int top=index.pop();
if (record[top]>0)
result=Math.max(result,record[top]*(matrix[0].length-index.peek()-1));
}
}
return result;
}
}