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.
[图片上传失败...(image-91728e-1513831694434)]
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!
一刷
题解:
- 像Container with most water一样,设立一个lo = 0, hi = height.length - 1,使用双指针来夹逼遍历。
- 设立一个res = 0, maxLeftBar = 0, maxRightBar = 0
- 在 lo <= hi的条件下进行遍历
- 假如height[lo] <= height[hi],或者height[lo] < height[hi]也可以, 这时候说明当前左边的height <= 右边的height。那么我们只需要考虑左边界和当前左边的height的差值,这个差值就是我们能容纳多少水
- 在上述情况下,假如height[lo] >= maxLeftBar, 当前index的值 > maxLeftBar,那么我们不能接到水,我们要把maxLeftBar更新为height[lo]
- 否则res += maxLeftBar - height[lo],我们把这个差值加入到结果中
- lo++
- 否则,左边的当前height > 右边的当前height,容易能盛多少水取决于右边的height以及maxRightBar的差值
- 当height[hi] >= maxRightBar,我们更新maxRightBar = height[hi]
- 否则,我们把结果 maxRightBar - height[hi]加入到res中
- hi--
- 最后返回结果res就可以了, 很巧妙。
Time Complexity - O(n), Space Complexity - O(1)
还有stack 和dynamic programming的方法留给二刷三刷
public class Solution {
public int trap(int[] height) {
if(height == null || height.length == 0) return 0;
int lo = 0, hi = height.length-1;
int maxLeftBar = 0, maxRightBar = 0;
int res = 0;
while(lo<=hi){
if(height[lo] <=height[hi]){
if(height[lo] >=maxLeftBar) maxLeftBar = height[lo];
else res += maxLeftBar - height[lo];
lo++;
}
else{
if(height[hi] >=maxRightBar) maxRightBar = height[hi];
else res += maxRightBar - height[hi];
hi--;
}
}
return res;
}
}
二刷思路同上
class Solution {
public int trap(int[] A) {
int res = 0;
int left = 0, right = A.length-1;
int maxLeft = 0, maxRight = 0;
while(left<=right){
if(A[left]<A[right]){//regard the right as wall
if(maxLeft<A[left]) maxLeft = A[left];
else res += maxLeft -A[left];
left++;
}else{
if(maxRight<A[right]) maxRight = A[right];
else res += maxRight -A[right];
right--;
}
}
return res;
}
}