第十章 單調棧 Part2

haohaoscnblogs發表於2024-09-03

目錄
  • 任務
    • 42. 接雨水
      • 思路
    • 84. 柱狀圖中最大的矩形
      • 思路

任務

42. 接雨水

給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。

思路

按照橫向計算,單調棧的思路得到 left和right,然後得到h 和 w,最終累加結果。

class Solution:
    def trap(self, height: List[int]) -> int:
        stack = []
        result = 0
        
        for i in range(len(height)):
            if len(stack) > 0 and height[i] <= height[stack[-1]]:
                stack.append(i)
            else:
                while len(stack) > 0 and height[i] > height[stack[-1]]:
                    mid = stack[-1]
                    stack.pop()
                    if len(stack) > 0:
                        left = stack[-1]
                        right = i
                        
                        h = min(height[left],height[right]) - height[mid]
                        w = right - left -1
                        result += h * w
                stack.append(i)
        return result

84. 柱狀圖中最大的矩形

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

思路

對於某根柱子,找到左邊第一個比它小的和右邊第一個比它小的,中間的部分即是當前柱子能夠構成的最大面積。需要注意在陣列左右兩邊新增0來保證首尾柱子的正確計算(或者理解為當特殊情況比如陣列單調遞增或單調遞減時的正確處理)

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        stack = []
        result = 0
        
        # 頭部尾部加0 
        heights.insert(0,0)
        heights.append(0)
        
        for i in range(len(heights)):
            if len(stack) > 0 and heights[i] >= heights[stack[-1]]:
                stack.append(i)
            else:
                while len(stack) > 0 and heights[i] < heights[stack[-1]]:
                    mid = stack[-1]
                    stack.pop()
                    if len(stack) > 0:
                        left = stack[-1]
                        right = i
                        
                        result = max(result,heights[mid] * (right - left -1)) 
                stack.append(i)
        return result

相關文章