直接回答:每个位置能接的水 = min(左侧最高柱, 右侧最高柱) − 自身高度(负数取 0)。三种实现:1)预处理左右最大值数组,O(n) 时间 O(n) 空间;2)双指针——左右指针向中间收缩,维护 leftMax 和 rightMax,谁小就结算谁那边(因为较小一侧的最大值已是瓶颈),O(n) 时间 O(1) 空间;3)单调递减栈按层结算,O(n) 时间 O(n) 空间。
展开解析:双指针版的正确性值得展开:当 leftMax < rightMax 时,左指针位置的接水量只取决于 leftMax(右边必有不低于 rightMax 的墙兜底),可以立即结算并右移;反之对称。单调栈版换了个视角:遇到更高的柱子时弹出栈顶作为「底」,栈中剩余元素作为「左墙」,当前柱作为「右墙」,按(宽 × 有效高度)横向累加水层。追问与变体:二维接雨水(用最小堆从边界向内做 BFS,木桶效应)、容器盛最多水(双指针收缩短板)、直方图类问题的统一视角——「瓶颈由两侧最大值决定」。
示例:
def trap(height):
lo, hi = 0, len(height) - 1
left_max = right_max = water = 0
while lo < hi:
if height[lo] < height[hi]:
left_max = max(left_max, height[lo])
water += left_max - height[lo]
lo += 1
else:
right_max = max(right_max, height[hi])
water += right_max - height[hi]
hi -= 1
return water