博客
关于我
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 中随机抽样:order by rand limit 的替代方案
    查看>>
    MySQL 为什么需要两阶段提交?
    查看>>
    mysql 为某个字段的值加前缀、去掉前缀
    查看>>
    mysql 主从
    查看>>
    mysql 主从 lock_mysql 主从同步权限mysql 行锁的实现
    查看>>
    mysql 主从互备份_mysql互为主从实战设置详解及自动化备份(Centos7.2)
    查看>>
    mysql 主从关系切换
    查看>>
    MYSQL 主从同步文档的大坑
    查看>>
    mysql 主键重复则覆盖_数据库主键不能重复
    查看>>
    Mysql 事务知识点与优化建议
    查看>>
    Mysql 优化 or
    查看>>
    mysql 优化器 key_mysql – 选择*和查询优化器
    查看>>
    MySQL 优化:Explain 执行计划详解
    查看>>
    Mysql 会导致锁表的语法
    查看>>
    mysql 使用sql文件恢复数据库
    查看>>
    mysql 修改默认字符集为utf8
    查看>>
    Mysql 共享锁
    查看>>
    MySQL 内核深度优化
    查看>>
    mysql 内连接、自然连接、外连接的区别
    查看>>
    mysql 写入慢优化
    查看>>