题目
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
.
![](http://www.leetcode.com/static/images/problemset/rainwatertrap.png)
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!
分析
思路是首先求得每个位置的水面高度,再由其求得水的体积。
而求水面高度,则可分为两种情况:
- 当前位置后有大于等于当前高度的位置,则自该位置起,将水面高度赋为当前高度
- 当前位置后没有大于等于当前高度的位置了,则自该位置之后,将水面高度赋为其之后的最高高度。
由于这两种情况都需要用到其后的最大高度,所以可以使用一个数组保存该值。另外别忘了每个位置的水面高度不能低于该位置的高度。
实现
class Solution {
public:
int trap(vector<int>& height) {
if(height.size()<=1) return 0;
int n = height.size();
int maxheight[n] = {0};
int maxpos[n] = {0};
int water[n] = {0};
maxheight[n-1] = height[n-1];
maxpos[n-1] = n-1;
for(int i=n-2; i>=0; i--){
if(height[i] >= maxheight[i+1]){
maxheight[i] = height[i];
maxpos[i] = i;
}
else{
maxheight[i] = maxheight[i+1];
maxpos[i] =maxpos[i+1];
}
}
int i=0;
while(i<n-1){
if(height[i]>=maxheight[i+1]){
water[i] = height[i];
for(int j=i+1; j<=maxpos[i+1]; j++){
water[j] = maxheight[i+1];
}
i = maxpos[i+1];
}
else{
int tmp = height[i];
while(i<n && height[i]<=tmp){
water[i] = tmp;
i++;
}
water[i] = height[i];
}
}
int ans = 0;
for(int i=0; i<n; i++){
ans += water[i] - height[i];
}
return ans;
}
};
思考
看了题解发现有更简单的思路:
- 扫描一遍, 找到最高的柱子,该柱子将数组分成左右两组
- 对于两组分别处理
参考代码
class Solution{
public:
int trap(const vector<int> &A){
const int n = A.size();
int max = 0; //最高的柱子,将数组分成两半
for (int i = 0; i < n; i++)
if (A[i] > A[max])
max = i;
int water = 0;
for (int i = 0, peak = 0; i < max; i++)
if (A[i] > peak)
peak = A[i];
else
water += peak - A[i];
for (int i = n - 1, top = 0; i > max; i--)
if (A[i] > top)
top = A[i];
else
water += top - A[i];
return water;
}
};
网友评论