42. [✔][H]接雨水
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
题解:
/*
* @lc app=leetcode.cn id=42 lang=typescript
*
* [42] 接雨水
*/
// @lc code=start
function trap(height: number[]): number {
// 双指针法
let lmax = 0, rmax = 0;//代表left左侧最高值和right右侧最高值
let left = 0;
let right = height.length - 1;
let res = 0;
while (left < right) {
lmax = Math.max(height[left], lmax);//更新left左侧最高值
rmax = Math.max(height[right], rmax);//更新right右侧最高值
if (lmax < rmax) {
// lmax小,说明left位置的雨水从lmax-自己的高度就可以
// 至于为什么left++,因为left位置已经加到res里面了,可以走下一个位置了
res += lmax - height[left];
left++;
} else {
res += rmax - height[right];
right--;
}
}
return res;
// 暴力破解法
// let n = height.length
// if (n === 0) {
// return 0;
// }
// let res = 0;
// let lMax: number[] = new Array(n);
// let rMax: number[] = new Array(n);
// lMax[0] = height[0];// 第一个数左侧最大值就是自己
// rMax[n - 1] = height[n - 1];// 最后一个数右侧最大值就是自己
// 记录第i位置左侧的最高柱子值
// for (let i = 1; i < n; i++) {
// lMax[i] = Math.max(height[i], lMax[i - 1]);
// }
// 记录第j位置右侧的最高柱子值
// for (let j = n - 2; j >= 0; j--) {
// rMax[j] = Math.max(height[j], rMax[j + 1]);
// }
// 从左到右依次计算每个柱子上可以接多少雨水,累加起来
// for (let i = 1; i < n - 1; i++) {
// res += Math.min(lMax[i], rMax[i]) - height[i]
// }
// return res;
};
// @lc code=end