給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。
求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
image.png
`
以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為 [2,1,5,6,2,3]
image.png
`
圖中陰影部分為所能勾勒出的最大矩形面積,其面積為10;個單位。
示例:`
輸入: [2,1,5,6,2,3]
輸出: 10`
思路:
用一個單調遞增的棧來放bar,如果是遞增的就放進棧,那么當前bar的左邊界就是前一個元素(比當前bar高度低的元素),循環數組的時候,遇到高度比棧頂bar高度低,說明找到了棧頂bar的右邊界,高度就是棧頂bar高度,寬度就是右邊界-左邊界(數組當前位置到棧bar前一個位置的距離,即i-stack[-2]-1)。每找到一個小于棧頂高度的需要循環和棧內元素做判斷并計算最大面積,計算完最大面積就彈出棧。height隊尾放入0是為了方便計算寬度,同時0高度最低,會把棧內元素面積都計算完。stack放入-1是為了方便計算左邊界。`
參考圖如下,不完全相同
image.gif
`
class Solution:
def largestRectangleArea(self, heights):
# 在隊尾加一個0方便計算寬度
heights.append(0)
# 新增一個單調遞增棧放矩形
stack = [-1]
area = 0
for i in range(len(heights)):
# 如果當前bar的高度height[i]低于棧頂bar高度,說明棧頂bar找到右邊界,且由于是單調遞增棧,棧頂前一個bar為左邊界stack[-2],則可以計算當前高度最大面積
while heights[i] < heights[stack[-1]]:
# 高度為棧頂bar高度
h = heights[stack[-1]]
# 寬度為左右邊界
w = i - stack[-2] - 1
area = max(area, h * w)
# 計算完最大面積后就彈出棧
stack.pop()
# 如果當前bar的高度height[i]大于等于棧頂,說明棧頂bar還沒找到右邊界,繼續放入棧
stack.append(i)
return area
su = Solution()
heights = [2, 1, 2]
res = su.largestRectangleArea(heights)
print(res)