Trapping Rain Water
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.
双指针法
复杂度
时间 O(N) 空间 O(1)
思路
我们使用两个指针,一个从左向右遍历,一个从右向左遍历。从左向右遍历时,记录下上次左边的峰值,如果右边一直没有比这个峰值高的,就已经加上这些差值。从右向左遍历时,记录下上次右边的峰值,如果左边一直没有比这个峰值高的,就加上这些差值。难点在于,当两个指针遍历到相邻的峰时,我们要选取较小的那个峰值来计算差值。所以,我们在遍历左指针或者右指针之前,要先判断左右两个峰值的大小。
注意
移动左指针或者右指针时,要先判断left < right
代码
public class Solution {
public int trap(int[] A) {
if(A.length < 3) return 0;
int left = 0;
int right = A.length - 1;
int sum = 0;
// 找到左边的第一个峰值
while(left < right && A[left] <= A[left+1]) left++;
// 找到右边的第一个峰值
while(left < right && A[right] <= A[right-1]) right--;
while(left < right){
int leftVal = A[left];
int rightVal = A[right];
// 如果左边峰值较小,先计算左边
if(leftVal < rightVal){
while(left < right && leftVal >= A[++left]){
sum += leftVal - A[left];
}
// 如果右边峰值较小,先计算右边
} else {
while(left < right && rightVal >= A[--right]){
sum += rightVal - A[right];
}
}
}
return sum;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。