84. 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.
Example:
Input: [2,1,5,6,2,3] Output: 10
题目大意
给出一个直方图,求可以组成的矩形的最大面积。
思路
暴力思想:遍历到第i个矩形时,向左和向右延伸,求其边界,然后求出以该矩形为最大高度时组成的矩形面积。这么做的时间复杂度是O(n^2)
单调栈思想:在遍历到第i个矩形时,我们可以使用单调栈来确定其左右边界,只需维护一个单调递增栈即可,若栈为空或者栈顶小于当前的高度,则将i入栈,为什么不将高度入栈的原因是根据i可以得到高度,而根据高度不一定得到i,如果栈顶大于当前高度heights[i],那么就则说明栈顶往右的边界是i-1,因为i是第一个比它小的。因为是单调递增栈,所以栈顶的下一个元素是它左边第一个比它小的,因此,以栈顶的高度为最大高度的矩形的宽度是i-1-t,t是栈顶下一个元素的索引。如果栈顶没有下一个元素,则宽度就是i。需要注意的是,此处需要在原始数组右边再加一个0,因为考虑到[1,1]的情况,如果不在原数组尾部增加0的话,在遍历第2个1时程序会退出,而不会计算以第2个1为最大高度的矩形。
代码
class Solution {
public int largestRectangleArea(int[] heights) {
int ans = 0;
if(heights.length == 0) return 0;
if(heights.length == 1) return heights[0];
Stack<Integer> s = new Stack<Integer>();
int i = 0 ;
heights = Arrays.copyOf(heights, heights.length + 1);
while(i < heights.length){
if(s.empty() || heights[i] > heights[s.peek()]){
s.push(i);
i++;
}
else{
int t = s.pop();
ans = Math.max(ans, heights[t] * (s.empty() ? i : i - 1 - s.peek()));
}
}
return ans;
}
}