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;
}
};