leetcode----Trapping Rain Water

原地址:https://leetcode.com/problems/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.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.


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. 

题意:给定一个数组,每一个值V_i,代表了以单位长度为宽,以V_i为高的实体(可以认为是水池的墙壁)。问给定的这样的『墙壁』可以剩多少水。即,求上图中蓝色区域的面积。

个人感觉,虽然leetcode官网上对这个题标的困难程度是Hard,但这个题还是比较好想的。它可以被认为是一个双向爬坡的问题。

首先,我们分析一下,什么样的两个『墙壁』可以独立装水并不被包含在其它『墙壁』之间呢?

从左往右看,能与当前『墙壁i』一起装水的另一个『墙壁j』的高度,至少是大于等于它的。如果不,则『墙壁j』则可能被『淹没』在『墙壁i』与另一个更高的『墙壁k』之间。

如果这样一个『墙壁j』没有出现,那么『墙壁i』就是最高的。

从右往左看,与上面类似。但这次只需扫描到上面得到的最高『墙壁』即可。

代码实现:

class Solution {
public:
    int trap(vector<int>& height) {
        
        if(height.size()==0) return 0;
        int sum = 0;
        // from left to right
        int left_max_idx = 0;
        for (int i = 1; i < height.size(); i++)
        {
            if(height[i] >= height[left_max_idx])
            {
                sum += (i - left_max_idx) * height[left_max_idx];
                for(int j = left_max_idx; j < i; j++)
                    sum -= height[j];
                left_max_idx = i;
            }
           
        }
        
        // from right to left
        int right_max_idx = height.size() - 1;
        for (int i = right_max_idx - 1; i >= left_max_idx; i--)
        {
            if(height[i] >= height[right_max_idx])
            {
                sum += (right_max_idx - i) * height[right_max_idx];
                for(int j = i+1; j <= right_max_idx; j++)
                    sum -= height[j];
                right_max_idx = i;
            }
        }
        
        return sum;
    }
};




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值