【Leetcode】42.接雨水

70 阅读1分钟

leetcode-42.png

题目简述:如图所示,也就是计算蓝色部分的高度总和。
我对于这题的思考就是,计算出每一个索引对应地方的最小高度即可。
思考第一步,如果这题最高的柱子出现在最最右边,那么就比较好解这一题了,从左往右,每次记录最高的柱子是多高,然后既可以记录下一个柱子的最大容量了

left.png 可以看下红色部分,这也就是最高柱子在最左边的情况。黄色部分就是最大的容量了。这就需要记录黄色部分之前的最高柱子的高度了。
根据这个思路,我们就可以记录下来这部分的最大容量数组了

maxLeft = [0,1,1,2,2,2,2]
// 计算红色部分的储水量就是
sum += height[i] - maxLeft[i]

有了这个思路,我们就可以对右半部分做相同的操作了

var trap = function (height) {
    let leftMax = [], rightMax = []
    let minHeight = []
    let maxheight = 0
    let sum = 0
    // 记录从左边算起的最高柱子能有多高
    for (let i = 0; i < height.length; ++i) {
        maxheight = Math.max(height[i], maxheight)
        leftMax[i] = maxheight
    }
    maxheight = 0
    // 记录从右边算起的最高柱子能有多高
    for (let i = height.length - 1; i >= 0; --i) {
        maxheight = Math.max(height[i], maxheight)
        rightMax[i] = maxheight
    }
    // 取其中的最小值来进行计算容量
    for (let i = 0; i < height.length; ++i) {
        minHeight[i] = Math.min(leftMax[i], rightMax[i])
        sum += minHeight[i] - height[i]
    }
    return sum
};

可以不使用minHeight这个数组

var trap = function (height) {
    let n = height.length;
    let leftHeight = new Array(n).fill(0);
    let rightHeight = new Array(n).fill(0);
    let leftMax = 0,
        rightMax = 0;
    for (let i = 0; i < n; ++i) {
        leftMax = Math.max(height[i], leftMax);
        leftHeight[i] = leftMax;
    }
    for (let i = n - 1; i >= 0; --i) {
        rightMax = Math.max(height[i], rightMax);
        rightHeight[i] = rightMax;
    }
    let sum = 0;
    for (let i = 0; i < n; ++i) {
        sum += Math.min(leftHeight[i], rightHeight[i]) - height[i];
    }
    return sum;
};