Trapping Rain Water
Question (LC.42)
Given an integer array representing the height of n unit width bars, find volume of rain water it can trap.
Example
I: [0,1,2]
O: 0
I: [3,1,2]
O: 1
I: [0,1,0,2,1,0,1,3,2,1,2,1]
O: 6Analysis
The water being trapped inside any bar is determined by the highest left and right bar. The volume of water trapped = min(left, right) - height
Brute Force Three Pass
We can assign the highest left bars, assign the highest right bars, then compute the rain water.
public int trap(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int n = height.length;
int[] leftBars = new int[n];
int[] rightBars = new int[n];
// assign left bars
int left = 0;
for (int i = 0; i < n; i++) {
left = Math.max(left, height[i]);
leftBars[i] = left;
}
// assign right bars
int right = 0;
for (int i = n - 1; i >= 0; i--) {
right = Math.max(right, height[i]);
rightBars[i] = right;
}
// compute the rain volume
int rain = 0;
for (int i = 1; i < n - 1; i++) {
int current = Math.min(leftBars[i], rightBars[i]) - height[i];
rain += current > 0 ? current : 0;
}
return rain;
}Time O(3n) = O(n) Space O(2n) = O(n)
L/R Pointers
Linear time is probably as good as we can get. Unless we can do a binary search on the array. But the space can be further optimized.
We maintain two values leftBar and rightBar. Then use left/right pointers to update on the way.
Time O(n) Space O(1)
Follow Up (LC.407)
Trap rain water 3D version
Last updated