Trapping Rain Water
Hard
📘 Problem Statement
Given an array of non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
🔍 Example
Example 1:
Input:
[0,1,0,2,1,0,1,3,2,1,2,1]
Output:
6
Explanation: The 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 are being trapped.
Example 2:
Input:
[4,2,0,3,2,5]
Output:
9
🧠 Key Insight
- Water can only be trapped if there are higher bars on both sides
- At any position, the amount of water trapped depends on the minimum of the maximum heights to the left and right, minus the height at the current position
- We can use a two-pointer approach to efficiently calculate this without pre-computing left and right max arrays
🛠️ Solution
def trap(height):
if not height or len(height) < 3:
return 0
left, right = 0, len(height) - 1
left_max = height[left]
right_max = height[right]
water = 0
while left < right:
if left_max < right_max:
left += 1
# Update left_max if current height is greater
left_max = max(left_max, height[left])
# Add trapped water at current position
water += left_max - height[left]
else:
right -= 1
# Update right_max if current height is greater
right_max = max(right_max, height[right])
# Add trapped water at current position
water += right_max - height[right]
return water
🕒 Time Complexity: \(O(n)\) where n is the length of the height array
📦 Space Complexity: \(O(1)\) as we only use constant extra space
💡 Explanation
- We use two pointers,
left
andright
, starting from the beginning and end of the array. - We maintain two variables,
left_max
andright_max
, to track the maximum height seen so far from the left and right sides. - At each step, we move the pointer from the side with the smaller maximum height:
- If
left_max < right_max
, we move the left pointer and update water trapped at that position - Otherwise, we move the right pointer and update water trapped at that position
- If
- The key insight is that if
left_max < right_max
, then the water trapped at the left pointer position is determined byleft_max
, regardless of heights between left and right. - Similarly, if
right_max < left_max
, the water trapped at the right pointer position is determined byright_max
. - This approach ensures we only need to traverse the array once.