[leetcode] 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 (at leetcode.com) for contributing this image!

Example:

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

Solution

本题的解法比较简单,先从左到右扫一遍,按照下面循环计算容量:

for(left = 0, right = 1; right < n; ++right) {
  if (height[left] <= height[right]) {
    left = right;
    capacity += part_capacity;
    part_capacity = 0;
  } else {
    part_capacity += height[left] - height[right];
  }
}

此时计算的容量中遗漏右低左高的情况,所以在从右到左扫一遍,按照下面循环计算容量:
注意:这两次循环除了颠倒了左右之外,还有一个地方是不同。
if 条件中,这里没有了等于符号。这两次扫描的结果之和就是最终结果。
之所以这样的两次扫描能得到最终结果而不会有重复的容量被计算在于,从左到右和从右到左的扫描结果只会在左边的高和右边的高相等时才有,所以第二次扫描不能有等号。

for (right = n - 1, left = n - 2; left > -1; --left) {
  if (height[left] > height[right]) {
    right = left;
    capacity += part_capacity;
    part_capacity = 0;
  } else {
    part_capacity += height[right] - height[left];
  }
}

提交的代码如下:

class Solution {
 public:
  int trap(vector<int>& height) {
    int n = height.size();
    int left, right, capacity = 0, part_capacity = 0;
    
    for(left = 0, right = 1; right < n; ++right) {
      if (height[left] <= height[right]) {
        left = right;
        capacity += part_capacity;
        part_capacity = 0;
      } else {
        part_capacity += height[left] - height[right];
      }
    }
    part_capacity = 0;
    for (right = n - 1, left = n - 2; left > -1; --left) {
      if (height[left] > height[right]) {
        right = left;
        capacity += part_capacity;
        part_capacity = 0;
      } else {
        part_capacity += height[right] - height[left];
      }
    }
    return capacity;
  }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值