Trapping Rain Water
HardThe problem
Each number in the list is the height of a bar, and every bar is 1 unit wide. After it rains, water collects in the dips between the bars. Return how many units of water are trapped in total.
- Example 1Input: height = [3, 0, 2, 0, 4]Output: 7
The water level across the middle is 3 (the lower of the two tall bars, 3 and 4). It fills 3 units over position 1, 1 unit over position 2 and 3 units over position 3: 3 + 1 + 3 = 7.
- Example 2Input: height = [2, 0, 2]Output: 2
The gap between the two walls of height 2 holds 2 units.
- Example 3Input: height = [1, 2, 3]Output: 0
The bars only go up, so no water stays.
- 1 ≤ height.length ≤ 100,000
- 0 ≤ height[i] ≤ 100,000
- Water that would spill off either end is lost
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
Water above one bar is limited by the tallest bar on its left and on its right — the smaller of the two.
The idea
Two pointers with leftMax and rightMax. Whichever side has the smaller max is the limiting side: add max − height for that side and move it.
Target: O(n) time, O(1) space
Go function shape
func trap(height []int) intReference solution
Tested with go test. Try it yourself first, then compare.
// Trap: water above a bar = min(tallest bar on its left, tallest bar on its right) - its height.
// Two pointers: the side with the SHORTER wall is the limiting side, so its water level is already known.
func Trap(height []int) int {
left, right := 0, len(height)-1
leftMax, rightMax, water := 0, 0, 0
for left < right {
if height[left] < height[right] {
leftMax = max(leftMax, height[left]) // the right wall is at least this tall, so leftMax limits
water += leftMax - height[left]
left++
} else {
rightMax = max(rightMax, height[right])
water += rightMax - height[right]
right--
}
}
return water
}