您的位置:首页 > 移动开发

[Leetcode 42] Trapping Rain Water

2017-07-07 21:32 465 查看
Question

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.




思路

对第一个不为0 的柱子,记录下它的位置t1, 遍历它之后的柱子(用 h 保存它之后的柱子的最高高度,记录相应位置t2), 遇到比t1柱子高的柱子或者遍历完数组停止。 h=min(t1,t2), 再从t1遍历到t2, 这样这可以找到t1与t2围成的最大容积。

重复这一过程,可以计算出所有的容积。该方法时间复杂度O(n2)。

代码如下:

class Solution {
public:
int trap(vector<int>& height) {
int ret=0;
for(auto it=height.begin(); it!=height.end(); ){
if(*it==0) ++it;
else{
//找到第一个不为0的柱子t1
decltype(it) it2=it, end_it;
int temp=*it;
int h=0;
++it2;
//遍历t1之后的柱子,找到其后第一个高度大于t1的柱子,若没有,则找到后面最高的柱子t2
while(it2 !=height.end()){
if(*it2>=h){
h=*it2;
end_it=it2;
}
if(*it2>temp) break;
++it2;
}
if(h==0 && it2==height.end()) break;
h=min(h, temp);
while(it!=end_it){
if(*it<h) ret+=(h-*it);
++it;
}
}
}
return ret;
}
};


下面是我在讨论区发现一个非常棒的解法,只需要维护目前的最高水位, 不断抛弃最左或者最右的低的柱子。 该方法只需要遍历一遍数组,时间复杂度O(n).

class Solution {
public:
int trap(vector<int>& height) {
if(height.empty()) return 0;
auto left=height.begin(),right=height.end()-1;
int level=0, water=0, lower=0;
while(left<right){
//找到较低的柱子
lower=*left<*right? *left++:*right--;
if(level<lower) level=lower;  //维护最高水位
else
water+=level-lower;  //可以容纳的水量
}
return water;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: