博客
关于我
42. 接雨水 动态编程 双指针
阅读量:798 次
发布时间:2023-04-16

本文共 2602 字,大约阅读时间需要 8 分钟。

动态规划与双指针方法解析:雨水收集问题的高效解决方案

动态规划方法解析

雨水收集问题是一道经典的算法题,目标是通过两个高度数组成的墙壁,计算能捕获的雨水总量。在本文中,我们将详细探讨两种高效解决方案:动态规划方法和双指针方法。

动态规划方法

动态规划是一种通过将问题分解成更小的子问题来解决复杂问题的方法。对于雨水收集问题,我们可以通过预先计算每个位置左边和右边的最大高度,来确定每个位置能捕获的雨水量。

具体步骤如下:

  • 初始化两个数组left_maxright_max,分别用于记录从左到右和从右到左的最大高度。
  • 从左到右填充left_max数组left_max[i] 表示从位置 0i 之间的最大高度。
  • 从右到左填充right_max数组right_max[i] 表示从位置 i 到末尾之间的最大高度。
  • 计算雨水总量:遍历每个位置 i,雨水量为 min(left_max[i], right_max[i]) - height[i],累加所有雨水量即可。
  • 这种方法的时间复杂度为 O(n),空间复杂度为 O(n),适用于处理较长的高度数组。

    双指针方法解析

    双指针方法是一种高效的两指针技术,常用于解决对称性较强的问题。本文将通过双指针方法来解决雨水收集问题。

    双指针方法

    双指针分别从数组的两端开始,向中间移动,比较当前位置的高度,确定哪一边的高度更高,然后计算当前位置能捕获的雨水量。

    具体步骤如下:

  • 初始化两个指针 leftright,分别指向数组的开头和末尾。
  • 初始化两个变量 left_maxright_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]))

    结论

    通过上述两种方法,我们可以高效地解决雨水收集问题。动态规划方法通过预先计算最大高度,确保每个位置的雨水量计算准确,而双指针方法则通过两指针技术,优化了空间复杂度,实现了更高效的解决方案。如果需要更深入的理解或优化,可以结合具体的应用场景选择最适合的方法。

    转载地址:http://sfgfk.baihongyu.com/

    你可能感兴趣的文章
    mysql 字段类型类型
    查看>>
    MySQL 字符串截取函数,字段截取,字符串截取
    查看>>
    MySQL 存储引擎
    查看>>
    mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
    查看>>
    MySQL 存储过程参数:in、out、inout
    查看>>
    mysql 存储过程每隔一段时间执行一次
    查看>>
    mysql 存在update不存在insert
    查看>>
    Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
    查看>>
    Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
    查看>>
    Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
    查看>>
    Mysql 学习总结(89)—— Mysql 库表容量统计
    查看>>
    mysql 实现主从复制/主从同步
    查看>>
    mysql 审核_审核MySQL数据库上的登录
    查看>>
    mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
    查看>>
    mysql 导入导出大文件
    查看>>
    mysql 将null转代为0
    查看>>
    mysql 常用
    查看>>
    MySQL 常用列类型
    查看>>
    mysql 常用命令
    查看>>
    Mysql 常见ALTER TABLE操作
    查看>>