# Time: O(N) # Space: O(N) class Solution: def trap(self, heights: List[int]) -> int: # Two pointer approach left, right = 0, len(heights) - 1 # Since while scanning the array, at a given index i, we # only need to consider the minimum of max_left_heights and # max_right_heights, we just need to keep moving from both # ends and keep track of the maximum height seen so far. We # can then compare these two heights and decide from which # side to move next. max_left = max_right = 0 output = 0 while left <= right: # By the formula from the DP approach: # # min(max_left, max_right) - heights[i] # # If max_left <= max_right, formula becomes: # # max_left - heights[i] # if max_left <= max_right: # Shorter form to avoid -ve values output += max(max_left - heights[left], 0) max_left = max(max_left, heights[left]) left += 1 # By the formula from the DP approach: # # min(max_left, max_right) - heights[i] # # If max_left > max_right, formula becomes: # # max_right - heights[i] # else: output += max(max_right - heights[right], 0) max_right = max(max_right, heights[right]) right -= 1 return output