1. 程式人生 > >❗️❗️❗️LeetCode Hard 84 最大直方圖矩形面積 Python

❗️❗️❗️LeetCode Hard 84 最大直方圖矩形面積 Python

def largestRectangleArea( height):
    """
    Disscussion Method
    演算法:單調棧
    思路:
        首先要明確所有可能的面積都是以某個矩形的高度為高而產生的矩形面積
        目標就是在所有這些矩形高度為height的矩形面積中找到最大的那個
        注意到原陣列內的元素是無序的,所以不能直接用動規那些,而且為了求矩形面積,也不能將陣列內的元素排序

        所以可以用單調棧來維護一個棧內元素單調遞增的棧,並且根據棧內的元素求矩形的面積
            以某個height做矩形高的矩形,一定是當前這個矩形是最低的了,即左右都沒有比他更低的元素,所以維護
        單調棧內的元素遞增,對height進行遍歷,如果當前元素大於棧頂,那麼將當前元素下標入棧,否則說明當前元素
        小於棧頂,而棧內元素又是遞增的,則:
            棧頂元素對應的高度就是當前要計算的矩形高
            h = heights[stack.pop()]
            此時的index = stack[-1]是左側第一個小於高度h的元素的下標,此時遍歷到的下標i是右邊第一個小於高度
        h的元素的下標,那麼以h為高的矩形,寬度w就是i-stack[-1]-1,然後更新ans = max(ans,w * h)

        ❗️❗️❗️:
            一定要理解到,當前的i是右側第一個小於h的下標,stack[-1]是左側第一個小於h的下標,所以求以h為高的矩形
        面積的時候,要把左側和右側的下標都找到才行!就像[2,1,2],ans = 3,就是以1為h,3為w

        這裡有兩個Trick:
            1. stack=[-1]保持stack內總是有元素的且總有元素是小於任何一個位置的,方便當stack內只剩下來自heights的
            一個元素時,計算w,選用-1是因為,heights中的元素都是非負的,所以左側用-1就可以保證是一個小於所有heights
            內元素的值
            2.heights.append(0),保持heights中最末尾總有一個小於所有元素的,這樣才可以在heights都append到stack後
            通過最末尾的這個0將stack中剩下的元素對應的面積全部求出來,
    """
    height.append(0)
    stack = [-1]
    ans = 0
    for i in range(len(height)):
        while height[i] < height[stack[-1]]:
            index = stack.pop()
            h = height[index]
            w = i - stack[-1] - 1
            ans = max(ans, h * w)
        stack.append(i)
    height.pop()
    return ans