題意
給定n個非負整數,表示每個小節的寬度爲1的直方圖的小節高度,找到直方圖中最大矩形的面積。
代碼
class Solution:
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
sta=[(-1,-1)]
n=len(heights)
left=[0 for i in range(n)]
right=[0 for i in range(n)]
for i in range(n):
head=sta[-1]
while(heights[i]<=head[1]):
sta.pop()
head=sta[-1]
left[i]=head[0]
sta.append((i,heights[i]))
sta=[(n,-1)]
for i in range(n-1,-1,-1):
head=sta[-1]
while(heights[i]<=head[1]):
sta.pop()
head=sta[-1]
right[i]=head[0]
sta.append((i,heights[i]))
maxx=0
for i in range(n):
if (right[i]-left[i]-1)*heights[i]>maxx:
maxx=(right[i]-left[i]-1)*heights[i]
return maxx
解題思路
顯然,我們可以枚舉i,對於每個i我們可以找到i左邊第一個比他小的,計爲left[i],找到i右邊第一個比他小的,計爲right[i],答案就是min((right[i]-left[i]-1)*heights[i]),這樣做是O(n^2)
我們如何快速找到right[i]和left[i]呢?我們可以用單調棧解決這個問題。枚舉i,然後我們從棧中找出left[i],如果棧頂元素大於等於heights[i],那麼把它彈出,因爲它不可能再影響到後面的left了(即對於後面的i,它不可能是第一個比後面的i小的元素),不斷重複這個操作,直到棧頂元素小於heights[i],棧頂元素的位置就是left[i],然後再把i樸實進去。rights同理。這樣時間複雜度爲O(n)