leetcode42接雨水

在这里插入图片描述

动态规划+双指针

class Solution:
    def trap(self, height: List[int]) -> int:
        # 动态规划
        n = len(height)
        leftMax = [height[0]] + [0] * (n-1)
        for i in range(1, n):
            leftMax[i] = max(leftMax[i-1], height[i])
        rightMax = [0] * (n-1) + [height[-1]]
        for i in range(n - 2, -1, -1):
            rightMax[i] = max(rightMax[i+1], height[i])
        ans = sum(min(leftMax[i], rightMax[i]) - height[i] for i in range(n))

        # 双指针
        left, right = 0, len(height) - 1
        leftMax = rightMax = 0
        ans = 0
        while (left < right):
            # 维护左边最高和右边最高的变量
            leftMax = max(leftMax, height[left])
            rightMax = max(rightMax, height[right])
            if height[left] < height[right]:
                # 更新左边
                ans += leftMax - height[left]
                left += 1
            else:
                # 更新右边
                ans += rightMax - height[right]
                right -= 1
        return ans

单调栈解法
维护一个单调递减栈(存放下标),因为当遍历的元素的高度大于栈顶元素高度,说明栈顶元素的位置出现了凹槽,需要计算雨水量
三种情况:
1)遍历元素<栈顶元素:直接入栈
2)遍历元素==栈顶元素:更新下标
3)遍历元素>栈顶元素:出现凹槽,计算雨水量,注意持续维护单调递减栈

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0
        # 维护一个单调递减栈,存下标
        stack = [0]
        for i in range(1, len(height)):
            # 小于栈顶元素,入栈
            if height[i] < height[stack[-1]]:
                stack.append(i)
            # 等于栈顶元素,更新下标
            elif height[i] == height[stack[-1]]:
                stack.pop()
                stack.append(i)
            # 大于栈顶元素,说明栈顶元素位置处出现凹槽,需要计算雨水量
            else:
                # 持续维护单调递减栈
                while stack and height[i] > height[stack[-1]]:
                    mid = stack.pop()
                    if stack:
                        left = stack[-1]
                        mid_height = height[mid]          # 中间高度
                        left_height = height[left]        # 左边高度:即栈中下一个元素
                        right_height = height[i]            # 右边高度:当前高度
                        res += (min(left_height, right_height) - mid_height) * (i - left - 1)
                stack.append(i)
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值