LeetCode 热题 HOT — 接雨水

120 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 13 天,点击查看活动详情

接雨水

原题地址

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

示例 1:

image.png

输入: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 *10410^4
  • 0 <= height[i] <=10510^5

思路分析

方法一

  1. 方法一依旧采用暴力解法;
  2. 两次遍历数组,找到当前元素左、右两侧的最大储水量,然后减去当前元素的值,即为当前元素的最大储水量;
  3. 将所有元素的最大储水量相加,即为总的最大储水量;
  4. 但是,采用暴力解法最后总是有可能得到超时的结果,因此还是要使用其他方法来解决。

方法二

  1. 分析题目,可知对于每个柱子能储多少水,在于它左边的最高柱子和右边的最高柱子,这两个中的最小值即为每个柱子的最大储水能力;
  2. 如果这个最小值减去柱子本身的值小于0,则证明这根柱子没办法储水,否则它的最大储水值就是最小值减去当前柱子的高度;
  3. 因此定义两个数组 leftright,分别表示 第i个柱子 左侧和右侧的最高柱子,循环遍历得出这两个数组的值;
  4. 然后按照步骤二分析,得出最终的最大储水值。

AC 代码

方法一

/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function(height) {
    let res = 0
    let len = height.length
    for (let i = 1; i < len - 1; i++) {
        let left = 0, right = 0
        for (let j = i; j >= 0; j--) {
            left = Math.max(left, height[j])
        }
        for (let j = i; j < len; j++) {
            right = Math.max(right, height[j])
        }
        res += Math.min(left, right) - height[i]
    }
    return res
};

结果:

  • 执行结果: 超出时间限制

方法二

/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function(height) {
    const len = height.length
    const left = new Array(len).fill(0)
    const right = new Array(len).fill(0)

    let max = height[0]
    for (let i = 1; i < len; i ++) {
        left[i] = max
        max = Math.max(max, height[i])
    }
    max = height[len - 1]
    for (let i = len - 2; i >= 0; i --) {
        right[i] = max
        max = Math.max(max, height[i])
    }

    let res = 0
    for (let i = 1; i < len - 1; i ++) {
        const cur = height[i]
        const min = Math.min(left[i], right[i])
        if (min > cur) {
            res += (min - cur)
        }
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:64 ms, 在所有 JavaScript 提交中击败了84.03%的用户
  • 内存消耗:43.6 MB, 在所有 JavaScript 提交中击败了36.58%的用户
  • 通过测试用例:321 / 321

END