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 heights = [2,1,5,6,2,3]
,
return 10
.
【解题思路】:对于高低不平的一个个矩形块,找出最大的矩形面积。可以申请一个栈s,维护递增的矩形条。当输入的矩形条高度大于栈顶矩形条高度,则将矩形条的位置入栈。直到输入的矩形条i高度小于栈顶矩形条高度,则将栈内高度大于矩形条i的矩形条一一弹出,计算面积area=当前弹出的矩形条k的高度*从矩形条i的位置开始到前面比k小的矩形条的位置为止(不包括这个比它小的矩形条的位置和i的位置)的横向距离;其中比刚弹出的矩形条k短的矩形条的位置,应该是弹出k后,此时栈顶元素所对应的矩形条高度。若弹出k后,栈空了,那么也就是说k矩形条之前没有比其更短的矩形条了,也就是矩形条i之前的所有矩形条高度都是大于k的。这个计算以矩形条k的高度为高的矩形面积的横向长度的公式用程序描述为:横向长度=s.empty()?i:i-s.top()-1; 为了计算所有的矩形条的面积,需要在heights的最后加上一个矩形条,高度为0;
以给出的例子为例,模仿计算过程:
首先栈是空的,那么矩形条0入栈,索引号i++,当i=1时,矩形条1的高度小于栈顶矩形条高度,则将栈顶矩形条位置弹出,计算area=2*1=2.
计算完area后,将矩形条1压入栈,然后i++,一直到i=4,矩形条4的高度小于栈顶高度。首先弹出栈顶元素矩形条3,计算area=height[3]*(4-2-1)=6,
接着弹出栈顶元素矩形条2,计算area=height[2]*(4-1-1)=10。不断更新area,得到最大值。直到矩形条1的高度小于矩形条4,结束计算。
将矩形条4压入栈中,矩形条5压入栈中,一直到最后一个元素0,小于栈顶元素。此时栈内有元素矩形条1、4、5 ,开始弹出栈内矩形条,计算面积。计算过程如下图所示。
以上就是该题的具体解决过程,那么这样的解题思路怎么能保证所计算的area中的最大值就是最大的矩形呢?
其实通过上述图解,可以看到这个过程是在求以每个矩形条为高度的最大面积,所以计算中的这些最大面积中的最大值就是最大的矩形面积。比如图1中以矩形条0为高度的最大矩形面积,图2是以矩形条4为高度的最大矩形面积,图3是以矩形条5为高度的最大矩形面积,等等。总共有6个矩形条,那么就共需要计算6次,6次计算中的最大值就是最大的矩形面积。该算法的时间复杂度为O(n)。
int largest_area(vector<int>& height) { stack<int> s; height.push_back(0); int result=0; for(int i=0;i<height.size();) { if(s.empty()||height[i]>height[s.top()]) { s.push(i++); } else { int tmp=s.top(); s.pop(); result=max(result,height[tmp]*(s.empty()?i:i-s.top()-1)); } } return result; }