42. 接雨水 动态编程 双指针
初始化两个数组: 从左到右填充 从右到左填充 计算雨水总量:遍历每个位置 初始化两个指针 初始化两个变量 初始化雨水总量 在两个指针指向不同的区域时: 当两个指针指向相同时,停止循环,返回雨水总量
发布日期:2025-06-19 07:12:51
浏览次数:3
分类:精选文章
本文共 2602 字,大约阅读时间需要 8 分钟。
动态规划与双指针方法解析:雨水收集问题的高效解决方案
动态规划方法解析
雨水收集问题是一道经典的算法题,目标是通过两个高度数组成的墙壁,计算能捕获的雨水总量。在本文中,我们将详细探讨两种高效解决方案:动态规划方法和双指针方法。
动态规划方法
动态规划是一种通过将问题分解成更小的子问题来解决复杂问题的方法。对于雨水收集问题,我们可以通过预先计算每个位置左边和右边的最大高度,来确定每个位置能捕获的雨水量。具体步骤如下:
left_max 和 right_max,分别用于记录从左到右和从右到左的最大高度。left_max数组:left_max[i] 表示从位置 0 到 i 之间的最大高度。right_max数组:right_max[i] 表示从位置 i 到末尾之间的最大高度。i,雨水量为 min(left_max[i], right_max[i]) - height[i],累加所有雨水量即可。这种方法的时间复杂度为 O(n),空间复杂度为 O(n),适用于处理较长的高度数组。
双指针方法解析
双指针方法是一种高效的两指针技术,常用于解决对称性较强的问题。本文将通过双指针方法来解决雨水收集问题。
双指针方法
双指针分别从数组的两端开始,向中间移动,比较当前位置的高度,确定哪一边的高度更高,然后计算当前位置能捕获的雨水量。具体步骤如下:
left 和 right,分别指向数组的开头和末尾。left_max 和 right_max,分别记录左边和右边的当前最大高度。ans 为 0。- 如果左边的高度小于右边的高度:
- 如果左边的当前高度大于
left_max,则更新left_max。 - 否则,计算当前位置能捕获的雨水量并累加到
ans。 - 移动左指针。
- 如果左边的当前高度大于
- 否则:
- 如果右边的高度大于
right_max,则更新right_max。 - 否则,计算当前位置能捕获的雨水量并累加到
ans。 - 移动右指针。
- 如果右边的高度大于
ans。这种方法的时间复杂度为 O(n),空间复杂度为 O(1),实现更加高效,适用于处理较短的高度数组。
代码实现与测试
以下是两个方法的代码实现:
from typing import Listclass Solution: def trap(self, height: List[int]) -> int: if not height: return 0 ans = 0 size = len(height) left_max = [0] * size right_max = [0] * size # 从左到右计算最大值 left_max[0] = height[0] for i in range(1, size): left_max[i] = max(height[i], left_max[i-1]) # 从右到左计算最大值 right_max[size-1] = height[size-1] for i in range(size-2, -1, -1): right_max[i] = max(height[i], right_max[i+1]) # 计算雨水量 for i in range(1, size): ans += min(left_max[i], right_max[i]) - height[i] return ansprint(Solution().trap([4, 2, 0, 3, 2, 5]))
from typing import Listclass Solution: def trap(self, height: List[int]) -> int: if not height: return 0 ans = 0 size = len(height) left = 0 right = size - 1 left_max = 0 right_max = 0 while left < right: if height[left] < height[right]: if height[left] >= left_max: left_max = height[left] else: ans += left_max - height[left] left += 1 else: if height[right] >= right_max: right_max = height[right] else: ans += right_max - height[right] right -= 1 return ansprint(Solution().trap([4, 2, 0, 3, 2, 5]))
结论
通过上述两种方法,我们可以高效地解决雨水收集问题。动态规划方法通过预先计算最大高度,确保每个位置的雨水量计算准确,而双指针方法则通过两指针技术,优化了空间复杂度,实现了更高效的解决方案。如果需要更深入的理解或优化,可以结合具体的应用场景选择最适合的方法。
发表评论
最新留言
很好
[***.229.124.182]2026年05月29日 22时58分40秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP OAuth 2.0 Server
2023-02-27
PHP pcntl_fork不能在web服务器中使用的变通方法
2023-02-27
php private ,public protected三者的区别
2023-02-27
php PSR规范
2023-02-27
php redis(2)
2023-02-27
PHP Redis分布式锁
2023-02-27
PHP SOAP模块的使用方法:NON-WSDL模式
2023-02-27
PHP SPL标准库-迭代器
2023-02-27
php zookeeper实现分布式锁
2023-02-27
PHP 使用 $_SERVER['PHP_SELF'] 获取当前页面地址及其安全性问题
2023-02-27
php 反射
2023-02-27
PHP 实现N阶矩阵相乘
2023-02-28
php 延迟静态绑定static关键字
2023-02-28
Redis入门
2023-02-28
PHP 截取字符串乱码的解决方案
2023-02-28
php 接口类与抽象类的实际作用
2023-02-28
PHP 插入排序 -- 折半查找
2023-02-28
PHP 支持8种基本的数据类型
2023-02-28