LeetCode解题 42:Trapping Rain Water
Problem 42: Trapping Rain Water [Hard]
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.
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!
Example:
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
来源:LeetCode
解题思路
每根柱子上的水面高度受其左右两边最高的那根柱子的影响,如果自己本身是最高点,则留不住水。
基本思路为从左往右和从右往左两次遍历,找出每一个柱子左边和右边的最高高度,取两数中较小值即为能困住的水面高度。
具体过程:
- 首先从左往右遍历数组,在
trapHeight[N]
中记录下每根柱子左边的最高点(max(trapHeight(i-1), height[i])
)。如果左边的柱子都不如自身高,则记录自身的高度。
如例图中输入,则trapHeiht
取值如下:
- 从右往左遍历数组,首先计算出每根柱子右边的最高点(
max(trapHeight[i+1], height[i])
),然后与左边最高点(trapHeight[i]
)作比较,选出较小的值即为当前柱子的水面高度。
例图中trapHeight
的值更改如下:
- 最后将每根柱子上的水面高度与自身高度之差累积,即为困住的雨水体积。
- 注意:数组最左边和最右边的的柱子本身一定为自身的最高点,因为二者左边或右边没有其他柱子,一定留不住比自己高的水面。
整个算法一共遍历了两次数组,时间复杂度为O(n),空间复杂度为O(n)。
运行结果:
Solution (Java)
class Solution {
public int trap(int[] height) {
int N = height.length;
if(N == 0) return 0;
int[] trapHeight = new int[N];
// max height on the left of each bar
trapHeight[0] = height[0];
for(int i = 1; i < N; i++){
trapHeight[i] = Math.max(trapHeight[i-1], height[i]);
}
// water height of each bar
trapHeight[N-1] = height[N-1];
for(int i = N-2; i >= 0; i--){
trapHeight[i] = Math.min(Math.max(trapHeight[i+1],height[i]),trapHeight[i]);
}
int water = 0;
for(int i = 1; i < N-1; i++){
if(trapHeight[i] > height[i]){
water += trapHeight[i] - height[i];
}
}
return water;
}
}
修改过程
- 第一次提交没有考虑N=0的情况。