LeetCode: 42. Trapping Rain Water

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.

1
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

就是每个位置给定一个海拔高度,宽度都是1,求下雨注满水之后这个横切面的面积是多少。

思路一:暴力求解法

2

我们从垂直方向上切分每个位置,例如这里的位置4,这个位置的需水量的高度是它左右两侧最高值中的较小值,比如左侧最高值是2,右侧最高值是3,但是很显然要取较小值2,所以它的水位高度是2,但是由于它本身海拔是1,所以还要减去1。这样遍历每个位置,求出各自位置上的面积,再相加,即可得出结果,代码如下:

Python 代码实现

class Solution:
    def trap(self, height: List[int]) -> int:
        ans = 0
        size = len(height)
        for i in range(size):
            max_left = 0
            max_right = 0
            for j in range(0,i+1)[::-1]:
                # Search the left part for max bar size
                max_left = max(max_left, height[j])
            
            for j in range(i,size):
                # Search the right part for max bar size
                max_right = max(max_right, height[j])
            
            ans += min(max_left, max_right) - height[i]
        
        return ans;

但是这样的时间复杂度是 O ( n 2 ) O(n^2) O(n2),不能ac。继续考虑其他方法。

思路二:动态规划

刚刚的暴力求解法,每次都要遍历左右两侧寻找最高值,其实每个位置的左右两侧最高值只要通过一次遍历保存即可。

Python 代码实现

class Solution:
    def trap(self, height: List[int]) -> int:
        if (height is None or len(height) == 0):
            return 0
        ans = 0
        size = len(height)
        left_max = [0] * size
        right_max = [0] * size
        left_max[0] = height[0]
        for i in range(size):
            left_max[i] = max(height[i], left_max[i - 1])
        
        right_max[size - 1] = height[size - 1]
        for i in range(0,size - 1)[::-1] :
            right_max[i] = max(height[i], right_max[i + 1])
        
        for i in range(0,size-1):
            ans += min(left_max[i], right_max[i]) - height[i]
        
        return ans

这样的时间复杂度是O(n)


THE END.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值