Problem Description
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Examples
Example 1: Input: height = [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: height = [4,2,0,3,2,5] Output: 9
Python Solution
def trap(height: List[int]) -> int:
if not height:
return 0
left, right = 0, len(height) - 1
left_max = right_max = water = 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
water += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
water += right_max - height[right]
right -= 1
return water
Java Solution
class Solution {
public int trap(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
int water = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}
return water;
}
}
C++ Solution
class Solution {
public:
int trap(vector& height) {
if (height.empty()) {
return 0;
}
int left = 0, right = height.size() - 1;
int leftMax = 0, rightMax = 0;
int water = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}
return water;
}
};
JavaScript Solution
/**
* @param {number[]} height
* @return {number}
*/
var trap = function(height) {
if (!height.length) {
return 0;
}
let left = 0, right = height.length - 1;
let leftMax = 0, rightMax = 0;
let water = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}
return water;
};
C# Solution
public class Solution {
public int Trap(int[] height) {
if (height == null || height.Length == 0) {
return 0;
}
int left = 0, right = height.Length - 1;
int leftMax = 0, rightMax = 0;
int water = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}
return water;
}
}
Complexity Analysis
- Time Complexity: O(n) where n is the length of the array
- Space Complexity: O(1) as we only use constant extra space
Solution Explanation
This solution uses the two-pointer technique to solve the problem efficiently. Here's how it works:
- Initialize two pointers:
- left pointer at the start of array
- right pointer at the end of array
- Keep track of maximum heights:
- leftMax: maximum height from left side
- rightMax: maximum height from right side
- For each step:
- If height[left] < height[right], process left side
- If height[right] ≤ height[left], process right side
- Add trapped water based on the difference between current height and max height
Key points:
- Uses two pointers for O(n) time complexity
- Maintains maximum heights from both sides
- Water can be trapped if current height is less than max height
- Process shorter walls first to ensure correct calculation