Trapping Rain Water

406 篇文章 0 订阅
406 篇文章 0 订阅

1,题目要求

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

给定n个非负整数表示每个柱的宽度为1的高程图,计算下雨后能够捕获的水量。

2,题目思路

对于这道题,是问一个有体积的蓄水池能蓄的水的总量。

之前有一道类似的题目,也是问最大能蓄多少水水:
Container With Most Water
不同之处在于,上面这道题不考虑蓄水池的体积问题,即仅仅是一个木桶问题的组合。

而目前这道题,是会考虑水池的体积的,因此,在是关水量的计算上,二者有所不同。不过相同的是,水总是会从较矮的一侧流出去。

因此,对于这道题,我们的思路是一个槽位一个槽位地去计算和判断。比如,对于序列[2,1,3],经过分析我们可以得知,此时可以容纳的水最多为1。
对于最左侧的墙柱和最右侧的墙柱,基于水的特性,我们始终从较矮的一侧开始遍历,这样可以保证另一侧(较高的)将水给拦住,不会流出去。

每当当前的墙柱比该侧的最高墙柱高时,我们就会更新最高的墙柱,而且此时高墙柱上不会蓄水。
而如果此时墙柱的高度比最高墙柱低时,我们就可以假想此时另一侧是一个空气墙(事实上另一个方向上的最大高度更高,保证不会流出去,可是并不一定是挨着当前的墙柱),这样,当前槽位的体积的计算就是:(maxHeight - heigt[i]) * 1

以这种方法,当左右遍历相遇时,就可以得到最后的结果了。

3,代码实现

static const auto s = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();

class Solution {
public:
    int trap(vector<int>& height) {
        int left = 0, right = height.size()-1;
        int res = 0;
        int maxLeft = 0, maxRight = 0;
        while(left <= right){
            //始终从较矮的那一侧遍历
            if(height[left]<=height[right]){
                if(height[left] >= maxLeft)
                    maxLeft = height[left];
                else
                    res += maxLeft - height[left];
                left++;
            }
            else{
                if(height[right] >= maxRight)
                    maxRight = height[right];
                else
                    res += maxRight - height[right];
                right--;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值