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

熵桥薄雾
• 阅读 3201

目录

之前看面试题的时候,看到了一个接雨水的问题,和小黄鸭讨论之后,觉得很有趣呢,这里和大家分享一下这个解法。后来看到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

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

问题分析

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

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

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

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

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

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

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

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

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

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

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

代码整理

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
};
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
10个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Karen110 Karen110
4年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
4年前
OpenJDK11与Spring Cloud Finchley的不兼容问题与解决
本文的环境:OpenJDK11.0.4,SpringCloudfinchleySR4,SpringBoot2.0.3最近遇到了一个问题,在feign调用的时候,时常会出现这样一个奇怪的错误:2019100708:00:00.620ERRORxxx,e1ba4c7540954aa3,871b99c4576d42e3
Stella981 Stella981
4年前
LeetCode 84.柱状图中最大矩形的面积
给定_n_个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为1。求在该柱状图中,能够勾勒出来的矩形的最大面积。!(https://img2018.cnblogs.com/blog/1735759/201907/1735759201907081935272741040149911.png)以上是柱状图的示例,其中
Stella981 Stella981
4年前
LeetCode 42. 接雨水
给定 _n_ 个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。!(https://oscimg.oschina.net/oscnet/b0cc4f8b9a129e159dc6141c019d5b3c043.png)上面是由数组\0,1,0,2,1,0,1,3,2,1,2,1\表示的高度图,在这种情况
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
贾蔷 贾蔷
4个月前
力扣面试17.21题解:接雨水问题的双指针最优解
一、问题描述给定n个非负整数表示每个宽度为1的柱子的高度,计算按此排列的柱子,下雨之后能接多少雨水。二、核心思想本解决方案采用:1.使用左右从两端向中间移动1.维护左右两边的最大值1.根据较小的一边计算当前能接的雨水量1.移动较小值的指针继续计算三、完整代