Use two pointers starting from both ends. Track leftMax and rightMax as you move inward.
The trick: at any position, water is limited by the shorter of the two maximums. If leftMax < rightMax, then the water at the left pointer is determined by leftMax alone. The right side is guaranteed to be at least as tall.
Process whichever side has the smaller maximum. If height[left] < height[right], we know leftMax <= rightMax. So compute water at left using leftMax, then move left inward.
This way, you only need one pass through the array, tracking two maximums as you go.