算法挑战35: 接雨水

0 阅读1分钟

题目:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

image.png

思路一:

一格一格来算,每一格宽度为1,求出来左右边的最小值,再减去当水桶底部的高度就ok了

为了知道每一格的左右边高度,我们用两个数组来存储

prev前缀,surf后缀

prev从前往后遍历,储存左边的最大高度

surf从后面遍历,储存右边的最大高度

哦哦哦,我们取的不是每一格左右边高度,而是最大高度

反正我们取得是最小高度

遍历三次

代码一:

var trap = function (height) {
    let len = height.length;
    let prev = [];
    let surf = [];
    let max = 0;
    let res = 0;
    for (let i = 0; i < len; i++) {
        let cur =height[i];
        max = max > cur ? max : cur;
        prev.push(max);
    }
    max = 0;
    for(let i = len - 1; i >= 0; i--){
        let cur = height[i];
        max = max > cur ? max : cur;
        surf.unshift(max);
    }
    for(let i = 0;i < len; i++){
        let cur = height[i];
        let capa = Math.min(prev[i],surf[i])- cur;
        res += capa;
    }
    return res;
};

思路二:

用相向双指针

优化空间复杂度

两个变量来储存最大前缀和最大后缀

以两者之间的较小值来计算当前格子的水容量

代码二:

var trap = function (height) {
    let len = height.length;
    let left = 0;
    let right = len - 1;
    let prev = 0;
    let surf = 0;
    let res = 0;
    while (left <= right) {
        prev = prev > height[left] ? prev : height[left];
        surf = surf > height[right] ? surf : height[right];
        if(prev < surf){
            res += prev - height[left];
            left++;
        }else{
            res += surf - height[right];
            right--;
        }
    }
    return res;
};