题意
给定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)