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