枚舉全部左右邊界,而後找到區間內的最小值。app
複雜度o(n^3)優化
耗時太久,故代碼略spa
選取以某個柱子爲高,而後左右擴散,保證沒有比他小的。code
複雜度o(n^2)blog
代碼略leetcode
這裏實際上是對暴力優化解法的一種優化,避免了重複的計算。get
維護一個單調棧,從小到大
每次遍歷一根柱子的時候,若是她比棧頂的大,就入棧,若是他比棧頂的小,就出棧,爲何?由於這個時候比他高的柱子爲高的矩形的右邊界已經能夠肯定了!
好比上圖中遍歷到2的時候,將6,5退棧一直到棧頂元素小於2,例子中也就是棧頂爲1的時候。爲何?這個時候5,6的右邊界已經肯定了,是2這根柱子(不包含這根),左邊怎麼肯定呢?很簡單,退棧6的時候他的左邊距就是棧頂元素,也就是5.爲何由於棧裏的元素都是遞增的,因此比他小且最大的元素必定在棧頂。it
這裏加了一些邊界值,方便判斷邊界狀況。io
複雜度:o(n)class
代碼以下:
from typing import List from collections import deque class Solution: def largestRectangleArea(self, heights: List[int]) -> int: queue, n, ans = deque(), len(heights), 0 queue.append(-1) heights.append(-1) for index, h in enumerate(heights[:n+1]): if h > heights[queue[-1]]: queue.append(index) else: while heights[queue[-1]] > h: t = queue.pop() left_index, right_index = queue[-1], index ans = max((right_index - left_index - 1) * heights[t], ans) queue.append(index) return ans