給定非負整數陣列 heights 表示柱狀圖各柱高度(寬度均為 1),找出能勻稱在柱狀圖內的最大矩形面積。
範例:heights = [2,1,5,6,2,3] → 最大面積 = 10(高度 5、寬度 2 的矩形,或高度 2、寬度 5 的矩形)。
最大矩形的高度必等於某根柱的高度。若固定高度為 heights[i],最大寬度為向左右擴展至首個高度 < heights[i] 的柱。暴力枚舉每根柱向兩側擴展為 O(n²)。
維護單調遞增棧存儲柱的索引。遍歷柱狀圖:
heights[i] ≥ heights[stk.top()] → 入棧tp,以 heights[tp] 為高計算面積:
i - stk.top() - 1(彈出後新棧頂為左側第一個更矮的柱)i(左邊無更矮柱)
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
heights.append(0) # 哨兵
stack = [-1] # 索引棧,-1 為左邊界
max_area = 0
for i, h in enumerate(heights):
while h < heights[stack[-1]]:
height = heights[stack.pop()]
width = i - stack[-1] - 1
max_area = max(max_area, height * width)
stack.append(i)
heights.pop() # 恢復原陣列(可選)
return max_area
以 [2,1,5,6,2,3] 為例:
| i | h | 棧狀態(索引) | 彈出計算 | 面積 |
|---|---|---|---|---|
| 0 | 2 | [-1, 0] | - | - |
| 1 | 1 | [-1, 1] | 彈出 0: h=2, w=1-(-1)-1=1 | 2 |
| 2 | 5 | [-1, 1, 2] | - | - |
| 3 | 6 | [-1, 1, 2, 3] | - | - |
| 4 | 2 | [-1, 1, 4] | 彈出 3: h=6, w=1; 彈出 2: h=5, w=2 | 6, 10★ |
| 5 | 3 | [-1, 1, 4, 5] | - | - |
| 6 | 0 | [-1] | 彈出 5,4,1 依次計算 | 3, 8, 6 |
單調棧是解決「區間最值邊界」問題的利器。本題通過「以每根柱為高的最大矩形」轉化,利用棧維護左側第一個更矮柱,右側在遍歷中自然確定,實現 O(n) 最優解。掌握「哨兵技巧」(頭尾添加邊界值)能大幅簡化邊界條件判斷。