一、核心公式
接雨水的核心逻辑:每个位置能存的水量,取决于它左右两侧最高墙中较矮的那个,减去当前墙的高度。
位置 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;
};
先从左到右算每个位置左侧最高墙,再从右到左算右侧最高墙,最后遍历累加。
四、总结
- 核心公式:min(左最高, 右最高) - 当前高度
- 双指针 O(1) 空间是面试最优解 > 3. 两种解法底层原理相同,区别只在最值存储方式