接雨水:左右最高墙的较小值减去当前高度

11 阅读1分钟

一、核心公式

接雨水的核心逻辑:每个位置能存的水量,取决于它左右两侧最高墙中较矮的那个,减去当前墙的高度。

位置 i 存水量 = min(leftMax[i], rightMax[i]) - height[i]

二、双指针解法(最优,O(1) 空间)

var trap = function(height) {
    let left = 0, right = height.length - 1;
    let leftMax = 0, rightMax = 0, res = 0;

    while (left < right) {
        if (height[left] < height[right]) {
            if (height[left] >= leftMax) leftMax = height[left];
            else res += leftMax - height[left];
            left++;
        } else {
            if (height[right] >= rightMax) rightMax = height[right];
            else res += rightMax - height[right];
            right--;
        }
    }
    return res;
};

哪边墙矮,哪边就决定当前蓄水上限——短板效应。双指针法在遍历过程中动态维护 leftMax 和 rightMax,不需要额外数组。

三、动态规划解法(易理解,O(n) 空间)

var trap = function(height) {
    const n = height.length;
    let leftMax = [], rightMax = [], res = 0;
    leftMax[0] = height[0];
    for (let i = 1; i < n; i++) leftMax[i] = Math.max(leftMax[i-1], height[i]);
    rightMax[n-1] = height[n-1];
    for (let i = n-2; i >= 0; i--) rightMax[i] = Math.max(rightMax[i+1], height[i]);
    for (let i = 0; i < n; i++) res += Math.min(leftMax[i], rightMax[i]) - height[i];
    return res;
};

先从左到右算每个位置左侧最高墙,再从右到左算右侧最高墙,最后遍历累加。

四、总结

  1. 核心公式:min(左最高, 右最高) - 当前高度
  2. 双指针 O(1) 空间是面试最优解 > 3. 两种解法底层原理相同,区别只在最值存储方式

cover.png