Trap Rain Water
Given an array of non-negative integers representing the heights of bars in a histogram, compute the amount of water that can be trapped between the bars after a rainfall.
The histogram is represented by an array where the width of each bar is 1. Water can be trapped if there are dips between taller bars that can hold the water.
Example
Input: [5, 0, 4] Output: 4 Explanation: Amount of water trapped is limited by shorter bar Input: [1, 1, 1] Output: 0 Explanation: No water can be trapped
Our solution processes the input array of heights by iterating through it while maintaining two pointers (left and right) and two variables (leftMax and rightMax) to track the maximum heights encountered from the left and right, respectively. We also use a variable (waterTrapped) to accumulate the total amount of water trapped.
For each element in the array:
- We compare the heights at the
leftandrightpointers. - If the height at the
leftpointer is less than the height at therightpointer:
- We move the
leftpointer to the right. - We update
leftMaxto be the maximum ofleftMaxand the current height atleft. - We calculate the water trapped above the current bar as
leftMax - height[left]and add this towaterTrapped.
- If the height at the
rightpointer is less than or equal to the height at theleftpointer:
- We move the
rightpointer to the left. - We update
rightMaxto be the maximum ofrightMaxand the current height atright. - We calculate the water trapped above the current bar as
rightMax - height[right]and add this towaterTrapped.
This process continues until the left pointer is greater than or equal to the right pointer.
The use of two pointers ensures that each element is processed efficiently, without the need for nested loops.
from typing import List
def trap_rain_water(height: List[int]) -> int:
if not height:
return 0
left, right = 0, len(height) - 1
left_max, right_max = height[left], height[right]
water_trapped = 0
while left < right:
if height[left] < height[right]:
left += 1
left_max = max(left_max, height[left])
water_trapped += left_max - height[left]
else:
right -= 1
right_max = max(right_max, height[right])
water_trapped += right_max - height[right]
return water_trappedTime Complexity: The solution has a time complexity of O(n), where n is the number of elements in the array. This is because we iterate through the array once, moving the left and right pointers towards each other.
Space Complexity: The solution uses O(1) space, as it only requires a constant amount of extra space for the pointers and variables (left, right, leftMax, rightMax, and waterTrapped), regardless of the input size.
Check out our lesson on the two-pointer approach to learn more about it and its applications!
from typing import List def trap_rain_water(height: List[int]) -> int: if not height: return 0 l, r = 0, len(height) - 1 leftMax, rightMax = height[l], height[r] res = 0 while l < r: if leftMax < rightMax: l += 1 leftMax = max(leftMax, height[l]) res += leftMax - height[l] else: r -= 1 rightMax = max(rightMax, height[r]) res += rightMax - height[r] return res # debug your code below print(trap_rain_water([5, 0, 4]))