【leetcode】-42. Trapping Rain Water困雨水

题目

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

在这里插入图片描述
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

暴力法

刚开始看到这题没有思路,可以看示例从局部开始分析,接最多的2格水,是因为左边最高的是2,右边最高的是3,自己本身的高度为0,所以能够蓄积到2格水。那么可以进行归纳总结,下标为 i 的地方的蓄水量应该是

water[i] = min(
               # 左边最高的柱子
               max(height[0..i]),  
               # 右边最高的柱子
               max(height[i..end]) 
            ) - height[i]

那么直接暴力遍历就可以出结果,但是leetode提交超时了。
需要注意的是,不管格子高度为多少,两边界是不可能会蓄水的。

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        n = len(height)
        res =0
        for i in range(1,n-1):
            l_max = max(height[:i+1])
            r_max = max(height[i:])
            temp = min(l_max,r_max)-height[i]
            res += temp
        return res
class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        n = len(height)
        res =0
        for i in range(1,n-1):
            l_max = 0
            r_max = 0
            for j in range(i,n):
                r_max = max(r_max,height[j])
            for j in range(i,-1,-1):
                l_max = max(l_max,height[j])
            res += min(l_max,r_max)-height[i]
        return res

备忘录优化

优化思想就是在暴力的解法上,将每个位置左右的最大数存储在一个数组中,后面用到时可直接取值,避免了重复的运算。

需要注意的是 l_max = [0]*n,r_max = [0]*n应该分开写,刚开始写成l_max = r_max = [0]*n一直得不到正确结果,是因为l_max与r_max是同一个地址空间,所以先计算的l_max会对r_max产生影响。

class Solution(object):
   def trap(self, height):
       """
       :type height: List[int]
       :rtype: int
       """
       if not height:
           return 0
       n = len(height)
       res = 0
       l_max = [0]*n
       r_max = [0]*n
       l_max[0] = height[0]
       r_max[n-1] = height[n-1]
       for i in range(1,n):
           l_max[i] = max(l_max[i-1],height[i])
       for i in range(n-2,-1,-1):
           r_max[i] = max(r_max[i+1],height[i])
       for i in range(1,n-1):
           res += min(l_max[i], r_max[i]) - height[i];
       return res

双指针

左右两边的指针并不是计算两指针中间的区域,而是左右同时计算各自的两边来提高效率。
左边的部分只与左边的最高柱子与本身的高度有关,右边的部分只与右边最高的柱子与本身的高度有关,到两指针相遇时,计算完毕。

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        if not height:
            return 0
        n = len(height)
        res = 0
        l = 0
        r = n-1
        l_max = height[0]
        r_max = height[n-1]
        while l<=r:
            l_max = max(l_max,height[l])
            r_max = max(r_max,height[r])
            if l_max < r_max:
                res += l_max - height[l]
                l += 1
            else:
                res += r_max - height[r]
                r -= 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值