042-trapping-rain-water
Question
https://leetcode.com/problems/trapping-rain-water/description/
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.
Example:
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6
Thought Process
- Brute Force
- For each element find it's max left boundary and right boundary
- The min of boundary decide how much water a column can store
- Deduct the height of current element, we got the amount of water can be stored at this index
- Time complexity O(n^2)
- Space complexity O(1)
- Optimized Brute Force - Two passes
- Instead keep search for its boundary, we can use cache to store the boundary
- Another optimization, we can make is that instead of use two passes to create left and right boundary cache, we can create left boundary on the go
- Time complexity O(n)
- Space complexity O(n)
- One pass
- Instead of use one pass to store the right boundary, we can use two pointers to track of boundaries
- As long as the one boundary is higher, we can accumulate the water from the opposite side
- Once the higher boundary switch side, we switch to the other side and start accumulate water
- Time complexity O(n)
- Space complexity O(1)
Solution
class Solution {
public int trap(int[] height) {
if (height == null || height.length <= 1) return 0;
int n = height.length;
int[] right = new int[n];
right[n - 1] = height[n - 1];
int rightMax = right[n - 1];
for (int i = n - 2; i >= 0; i--) {
rightMax = Math.max(rightMax, height[i]);
right[i] = rightMax;
}
int leftMax = Integer.MIN_VALUE;
int water = 0;
for (int i = 0; i < n; i++) {
leftMax = Math.max(leftMax, height[i]);
water += Math.min(leftMax, right[i]) - height[i];
}
return water;
}
}
One pass
class Solution {
public int trap(int[] height) {
if (height == null || height.length <= 1) return 0;
int n = height.length;
int left = 0, right = 0;
int lo = 0, hi = n - 1;
int water = 0;
while (lo < hi) {
left = Math.max(left, height[lo]);
right = Math.max(right, height[hi]);
if (left > right) {
water += right - height[hi];
hi--;
} else {
water += left - height[lo];
lo++;
}
}
return water;
}
}