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