用简单思维解决LeetCode中困难级别的题 —— 接雨水问题

目录

之前看面试题的时候,看到了一个接雨水的问题,和小黄鸭讨论之后,觉得很有趣呢,这里和大家分享一下这个解法。后来看到LeetCode上面有这道题,题号42,有兴趣的可以做一下。

问题描述

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

示例1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6

实例2:

输入:height = [4,2,0,3,2,5]
输出:9

你能不能先思考一下,遇到这种问题,你要怎么做呢?

问题分析

首先我们可以根据给的数组,先画出来柱子的长度。

柱子长度.png

那么我们怎么确定接的雨水的量呢?当然是两个都高中间低的地方,来存储水,下面阴影的部分就是储存水的位置。

雨水部分.png

那么我们需要对左边和右边最高水位做一个统计,这边使用到了两个辅助数组

一个用来储存左边的最大接雨水数,一个存储右边的最大接雨水数。

最大接雨水数.png

选择两个中最小的那个作为存储水的量

QQ图片20210421181221.png

当然还要减去自己柱子的高度。剩下的,就是可以接的雨水了。

QQ图片20210421181257.png

代码整理

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    // 把左右最大出水量求出来
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    // 算出最小的然后累加
    for(let i = 0; i < len; i++) {
        result += Math.min(left[i],right[i]) - height[i]
    }
    return result
};

如果想要写法上优化一下,可以第二次遍历的时候可以使用reduce

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    return height.reduce((prev, item, index) => {
        return prev + Math.min(left[index],right[index]) - item
    }, 0)
};

分析

  • 时间复杂度O(n)
  • 空间复杂度O(n)

其实右边数组的值的存储是可以省略的,虽然都是空间复杂度O(n),但是也算小小的优化点。

function trap(height) {
    if(!height.length) return 0;
    let left = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        left[i] = lmax
    }
    // 从后往前遍历
    for(let i = len - 1; i >= 0; i--) {
        rmax = Math.max(height[i], rmax)
        result += Math.min(left[i],rmax) - height[i]
    }
    return result
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 上面是由...
    suoxd123阅读 3,411评论 0 0
  • 1.问题描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。高...
    不辍居阅读 4,028评论 0 1
  • 【题目】: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 上...
    myf008阅读 3,211评论 0 0
  • 读完本文,你可以去力扣拿下如下题目: 42.接雨水[https://leetcode-cn.com/problem...
    labuladong阅读 3,987评论 0 5
  • 给定n个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水 https://le...
    Shimmer_阅读 1,748评论 0 1