【LeetCode 刷题】单调栈(2)-接雨水

此博客为《代码随想录》单调栈章节的学习笔记,主要内容为单调栈接雨水问题的相关题目解析。

42. 接雨水

题目链接

class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        stk = []
        res = 0
        for i in range(n):
            while stk and height[i] > height[stk[-1]]:
                mid = stk.pop()
                if not stk: break
                left, right = stk[-1], i
                h = min(height[left], height[right]) - height[mid]
                w = right - left - 1
                res += h * w
            stk.append(i)
        return res
  • 栈从栈顶到栈底递增,若当前元素 > 栈顶,则弹出栈顶元素;
  • 此时如果栈不为空(为空则表明到达坐标轴边界了,无法接到雨水),则表明构成一个接雨水的区域:栈顶元素作为 mid,次顶元素作为 left,当前元素作为 right,统计面积

84. 柱状图中最大的矩形

题目链接

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        heights = [0] + heights + [0]
        n = len(heights)
        res = 0
        stk = []
        for i in range(n):
            while stk and heights[i] < heights[stk[-1]]:
                mid = stk.pop()
                left, right = stk[-1], i
                h = heights[mid]
                w = right - left - 1
                res = max(res, h * w)
            stk.append(i)
        return res
  • 与接雨水正好相反,找中间高两边低的三元组来画矩形
  • 需要在原始 height 数组中额外添加首尾两个 0 用于收集两个边界的结果(接雨水不需要添加因为边界无法收集雨水,但此题即使有边界也能够正常画出矩形)
  • 其余思路和接雨水类似

407. 接雨水 II

题目链接

class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        m, n = len(heightMap), len(heightMap[0])
        h = []
        for i, row in enumerate(heightMap):
            for j, height in enumerate(row):
                if i == 0 or i == m - 1 or j == 0 or j == n - 1:
                    h.append((height, i, j))
                    row[j] = -1  # 标记 (i,j) 访问过
        heapify(h)

        ans = 0
        while h:
            min_height, i, j = heappop(h)  # min_height 是木桶的短板
            for x, y in (i, j - 1), (i, j + 1), (i - 1, j), (i + 1, j):
                if 0 <= x < m and 0 <= y < n and heightMap[x][y] >= 0:  # (x,y) 没有访问过
                    # 如果 (x,y) 的高度小于 min_height,那么接水量为 min_height - heightMap[x][y]
                    ans += max(min_height - heightMap[x][y], 0)
                    # 给木桶新增一块高为 max(min_height, heightMap[x][y]) 的木板
                    heappush(h, (max(min_height, heightMap[x][y]), x, y))
                    heightMap[x][y] = -1  # 标记 (x,y) 访问过
        return ans
  • 三维接雨水,无法使用单调栈,此解法基于“短板效应”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值