Leetcode 84:柱狀圖中最大的矩形(超詳細的解法!!!)
阿新 • • 發佈:2018-12-19
求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為 [2,1,5,6,2,3]
。
圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10
個單位。
示例:
輸入: [2,1,5,6,2,3]
輸出: 10
解題思路
這個問題非常有意思。我們首先可以想到的是暴力破解,我們通過i
不斷遍歷heights
,然後在遍歷的過程中通過j
不斷向後尋找最大矩形。
例如,我們把i
從1
開始遍歷,j
在[i,len(heights)]
區間遍歷。
class Solution:
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
if not heights:
return 0
heights_len = len(heights)
res = 0
i, j = 0, 0
while i < heights_len:
min_h = heights[ i]
for j in range(i, heights_len):
min_h = min(min_h, heights[j])
res = max(res, min_h*(j - i + 1))
i += 1
return res
這種解法顯然很慢,我們有一種更好的思路就是通過遞增棧。所謂的遞增棧,就是棧中只存放遞增序列。
我們首先將2
加入到棧中,我們接著訪問1
,我們發現1
2
小,所以我們將棧頂元素2
彈出,並且記錄此時的面積2
。我們發現棧已經空了,所以我們要接著壓棧。
接著我們通過不斷遍歷找到第二個遞增棧。
我們接著訪問2
,我們發現此時2
比棧頂元素6
小,所以我們彈出棧頂元素6
,並且記錄此時的面積6*1=6
。
此時棧中還有元素,我們發現此時2
依舊比棧頂元素5
大,所以我們需要將棧頂元素5
彈出,並且我們記錄此時出棧元素構成的最大面積5*2=10
。
我們發現此時的2
比棧頂元素大了,我們就將2
壓入棧中,接著將3
壓入棧中。此時遍歷結束,我們發現棧不為空,所以我們需要進行出棧操作,出棧的同時記錄出棧元素構成的最大面積即可。
class Solution:
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
stack = list()
res, i = 0, 0
while i < len(heights):
if not stack or (heights[i] >= heights[stack[-1]]):
stack.append(i)
i += 1
else:
k = stack.pop()
res = max(res, heights[k]*((i - stack[-1] - 1) if stack else i))
while stack:
k = stack.pop()
res = max(res, heights[k]*((i - stack[-1] - 1) if stack else i))
return res
我將該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!