1. 程式人生 > >用棧來實現求陣列中每個元素的左邊第一個小和右邊第一個小 -2014-03-26 20:35

用棧來實現求陣列中每個元素的左邊第一個小和右邊第一個小 -2014-03-26 20:35

陣列中每個元素的左邊第一個小和右邊第一個小:
如[2,1,5,6,2,3]中5左邊第一個小的元素是1,右邊第一個小的元素是2;

如何在複雜度為O(n)的情況下計算出所有元素的左邊第一個小和右邊第一個小?

這是leetcode中的“

Largest Rectangle in Histogram

”,原題是求柱狀圖中面積最大的矩形。
如:
的面積最大矩形就是圖中的陰影部分,即10;

開始我只想到方法一,提交後超時, 看discuss中才知道第二、第三種方法,第二種方法雖然複雜度低點,但編寫的難度不會低。
方法(1):求出所有以i為左邊,j為右邊的區域面積,  同時求最大面積值。   n*n超時!
方法(2):分治法  nlogn
方法(3):動態規劃, 求出以i為最短條的區域面積,
            該區域的面積需要通過左第一個比i短的條j的下標,及右第一個比i短的條k的下標,該區域面積即為height[i]*(k-j-1);

方法三就涉及到如何求元素i的左邊第一個小和右邊第一個小,即開頭所描述的問題。

答案是用棧!(當然也可以用別的資料結構,如陣列、排序佇列priority_queue
,)
棧中,棧底到棧頂是從小到大的順序;
for i=0 to n,
    如果棧頂元素比i大,則彈出棧頂元素,此時棧頂元素的右面第一個小元素就是i。繼續,知道棧頂元素比i小或棧為空;
    元素i進棧;

總之,在棧裡時,某元素的底下一個元素(可能沒有)就是其左面第一個小,元素出棧時,就可以得到其右面第一個小!