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. Thanks Marcos for contributing this image!
题目:这道题是前两天欠着的,感觉没什么思路,今天百度了一下发现原来是如此简单,为什么没思考不到呢。。。
思路:找出最高的坐标,然后从两边开始遍历,因为一最高的为基准点,所以从两边遍历,例如左边,只要左边的值比右边的值大,就可以蓄两者差值的水。最大值的右边同样的道理。
public int trap(int[] height) {
if(height.length <= 3) return 0;
int len = height.length;
int max = 0;
int maxId = 0;
for(int i = 0; i < len;i++) {//找出最大值
if(height[i] > max) {
max = height[i];
maxId = i;
}
}
int area = 0;
int n = height[0];
for(int i = 0; i < maxId;i++) {
if(n < height[i]) {
n = height[i];
} else {
area += n - height[i];//蓄水(两者的差值)
}
}
n = height[len-1];
for(int i = len-1;i > maxId;i--){
if(n < height[i]) {
n = height[i];
} else {
area += n - height[i];
}
}
return area;
}
还看了另一种思路,可能理解起来比上面那种困难一些。
public int trap1(int[] height){
if(height.length <=3) return 0;
int l =0, r = height.length-1;
int area = 0;
while(l < r) {
while(l<r && height[l] == 0) l++;//找到不是0的位置
while(l<r && height[r] == 0) r--;
int min = Math.min(height[l], height[r]);//找短的边
int tmp = 0;
for(int i = l ; i <=r;i++) {
if(height[i] > min) {
height[i] -= min;//如果比短的边大,那不能蓄水,同时把这一层砍掉
} else {
tmp += min - height[i];//比短的边小,可以蓄水
height[i] = 0;//蓄过水的位置也要砍掉,相当于把底层削掉
}
}
area += tmp;
}
return area;
}