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 =10unit.
For example,
Given height =[2,1,5,6,2,3],
return10.
題意:求直方圖中最大的矩形面積
思路:比較直接的方式是,遍歷數組,計算以每個值為起點的最大面積,取其最大值,如題中例子,值得注意的是,以2為起點,遍歷到5時,應該是1*3=3,即取最小值相乘。但其時間復雜度為O(n^2)。於是上網找到了實驗室小紙貼校外版的博客,其給出了時間復雜度為O(n)的算法。其主要的思想是:用一個棧來保存下標(索引),遇到比棧中下標對應的值大的高度時,就將這個這個高度的下標壓入棧中,即保證棧中下標對應的高度是非降型的;遇到比棧中下標對應值小的高度,就計算此時的面積,和res比較,取較大值。為了保證到最后時依舊存在一個不升狀態,即結束狀態,要在height中壓入一個0。下面結合自己的想法給出詳細的說明。
以題中例子:height =[2,1,5,6,2,3],
1) 剛開始棧中為空,壓入下標0;然后當i=1時,2<=1不成立,下標出棧,棧變為空,計算此時面積res=2;
2)高度1,5,6是依次遞增的,所以對應下標依次壓入棧中;當i=4時,6>2,下標3出棧,所以計算此時的面積res=6,如圖:
3)棧頂元素為2,其對應的高度為5>2(此時,還要和下標i=4的高度比較),所以,棧頂元素2出棧,計算面積為res=10;
4)因為棧頂元素為1,其對應的高度為1<2,滿足條件,所以,將i入棧,直到i=6(為壓入的0);此時棧中的元素為{1,4,5},有一個棧頂元素對應的高度大於i=6對應的高度,所以,5出棧,計算面積為3,其中最大面積為10;
5)棧頂元素為4,其對應高度為2>0,所以,2出棧,計算面積為4,最大面積為10;
6) 此時,棧頂元素為1,對應高度為1>0,所以,1出棧,因為1出棧以后,棧變為空,所以,計算面積的方式有變化,res=height[1]*6=6,最大面積為10。
代碼如下:
1 class Solution { 2 public: 3 int largestRectangleArea(vector<int> &height) 4 { 5 int res=0; 6 stack<int> stk; 7 height.push_back(0); 8 for(int i=0;i<height.size();++i) 9 { 10 if(stk.empty()||height[stk.top()]<=height[i]) 11 stk.push(i); 12 else 13 { 14 int temp=stk.top(); 15 stk.pop(); 16 res=max(res,height[temp]*(stk.empty()?i:(i-stk.top()-1))); 17 --i; 18 } 19 } 20 return res; 21 } 22 };
總結:主要的思想是用棧維護一個高度非降型的下標,若是有降,則計算面積,直到重新回到非降型。所以,為維護到最后時,能計算面積的情況,需在最后加入0