原地址: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;
}
};