题目42—接雨水

文章介绍了如何使用单调栈算法解决LeetCode中的问题,计算在给定非负整数表示的柱子高度图中,雨水接集的最大容量。通过找到凹槽并找出左右两侧的第一个最高柱子来计算雨水接集量。

题目来源于LeetCode

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

 方法:使用单调栈。找到中间凹槽位置,并利用单调栈找出其左边的第一个最高柱子,右边的第一个最高柱子即循环遍历到的这一个元素。

# 单调栈(单增栈)
# 若当前遍历元素大于栈顶元素,则出现凹槽

height = [4, 2, 0, 3, 2, 5]

list = []
s = 0

for i, v in enumerate(height):
    while list and v > height[list[-1]]:
        top = list.pop()
        if list:
            left = list[-1]
            wid = i - left - 1
            hei = min(height[left], height[i]) - height[top]
            s += wid * hei
        else:
            break
    list.append(i)
print(s)  # 9

 

### 动态规划解法 动态规划是一种解决“雨水”问题的经典方法。该方法的核心思想是通过预处理数组来记录每个位置左边和右边的最大高度,从而计算每个位置能够存储的雨水量。 具体步骤如下: - 创建两个数组 `left_max` 和 `right_max`,分别记录从左到右和从右到左的最大高度。 - 遍历数组,计算每个位置的 `left_max` 和 `right_max`。 - 每个位置能够存储的雨水量为 `min(left_max[i], right_max[i]) - height[i]`。 以下是该方法的实现代码: ```python def trap(height): if not height: return 0 n = len(height) left_max = [0] * n right_max = [0] * n left_max[0] = height[0] for i in range(1, n): left_max[i] = max(left_max[i-1], height[i]) right_max[n-1] = height[n-1] for i in range(n-2, -1, -1): right_max[i] = max(right_max[i+1], height[i]) total_water = 0 for i in range(n): total_water += min(left_max[i], right_max[i]) - height[i] return total_water ``` ### 双指针解法 双指针解法是一种优化的解决方案,它通过两个指针从数组的两端向中间移动,从而减少空间复杂度[^2]。 具体步骤如下: - 初始化两个指针 `left` 和 `right`,分别指向数组的开始和结束。 - 维护两个变量 `left_max` 和 `right_max` 来记录当前指针位置的最大高度。 - 如果 `height[left] < height[right]`,则 `left_max` 必定小于 `right_max`,此时 `left` 位置的雨水量为 `left_max - height[left]`,然后将 `left` 向右移动一位。 - 否则,`right` 位置的雨水量为 `right_max - height[right]`,然后将 `right` 向左移动一位。 以下是该方法的实现代码: ```python def trap(height): if not height: return 0 left, right = 0, len(height) - 1 left_max, right_max = 0, 0 total_water = 0 while left < right: if height[left] < height[right]: if height[left] >= left_max: left_max = height[left] else: total_water += left_max - height[left] left += 1 else: if height[right] >= right_max: right_max = height[right] else: total_water += right_max - height[right] right -= 1 return total_water ``` ### 总结 动态规划和双指针解法各有优劣。动态规划的空间复杂度较高,但逻辑清晰易懂;而双指针解法则空间复杂度较低,适合处理大规模数据。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值