算法第三十一天-直方图的水量

本文介绍了如何通过暴力法、动态规划和双指针优化算法解决直方图上的雨水收集问题,重点讨论了三种方法的实现思路、复杂度分析以及空间和时间效率提升。
摘要由CSDN通过智能技术生成

直方图的水量

题目要求

在这里插入图片描述

解题思路

使用面向列的计算比面向行的计算更加容易。我们只需要考虑当前的位置的左右最高模板的高度。

方法一、暴力解法

每个位置能接到多少雨水,很容易想到[木桶效应],即是由两边最短的木板限制的。那么直观思路就是,对于每个位置,向左右找最高的木板,当前位置能放的水量是:左右两边最高木板的最低高度-当前高度。

方法二、动态规划

从暴力法向两边求最高木板,这里其实是有重复计算的。比较直观的优化思路是:先提前遍历一次,求出每个位置左右最高的模板,把结果保存在数组里。就可以避免求解雨水的for循环中计算高度了。

方法三、双指针

双指针解法是上面的解法的进一步优化,主要作用是为了降低空间复杂度。
使用了两个指针leftright分别指向左右两个端点的柱子。
另外用lHeightrHeight分别表示左右两个指针遇到过的最高的柱子,注意上面的动态规划做法是提前计算出来每个位置的最高柱子。
双指针移动的思想是看left和right两个柱子那个更矮,因为蓄水时的瓶颈时更矮的柱子,而更高的柱子其实是不用考虑的。所以每次把更爱的柱子向中间移动。

代码

暴力法

class Solution:
    def trap(self, height: List[int]) -> int:
        res=0
        for i in range(1,len(height)-1,1):
            lHeight=max(height[:i])
            rHeight=max(height[i+1:])
            h = min(lHeight,rHeight) - height[i]
            if h>0:
                res +=h
        return res

动态规划

N=len(height)
        if N<2:return 0
        lHeight=[0]*N
        lHeight[0] = height[0]
        rHeight=[0]*N
        rHeight[N - 1] = height[N - 1]
        for i in range(1,N):
            lHeight[i] = max( lHeight[i-1], height[i])
        for i in range(N-2,-1,-1):
            rHeight[i]=max(rHeight[i+1], height[i])
        res=0
        for i in range(N):
            h = min(lHeight[i],rHeight[i])-height[i]
            if h >0:
                res +=h
        return res
        

双指针

class Solution(object):
    def trap(self, height):
        N = len(height)
        if N < 2: return 0
        left, right = 0, N - 1
        lHeight = rHeight = 0
        res = 0
        while left < right:
            if height[left] < height[right]:
                if height[left] < lHeight:
                    res += lHeight - height[left]
                else:
                    lHeight = height[left]
                left += 1
            else:
                if height[right] < rHeight:
                    res += rHeight - height[right]
                else:
                    rHeight = height[right]
                right -= 1
        return res

复杂度分析

暴力法动态规划双指针
时间复杂度 O ( N 2 ) O(N^2) O(N2) O ( N ) O(N) O(N) O ( N ) O(N) O(N)
空间复杂度 O ( 1 ) O(1) O(1) O ( N ) O(N) O(N) O ( 1 ) O(1) O(1)
  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

alstonlou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值