42. 接雨水

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

示例 1

输入: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

思路:

接雨水问题也是一个经典+高频问题。高频问题都是有技巧和套路的。对于接雨水问题,我们要知道每一处(竖直)可容纳的雨水量,然后将它们相加就是最终结果了。一定要细分开来,否则是很难有效计算的。

如何计算每一竖直上的雨水量呢?首先抛出一个结论:每处(竖直)可容纳的雨水高度取决于左右两边的(比它高的)最高的柱子中,较矮的那个。得到这个值后,减去自身高度,就是这一列的容量。

如果左边没有比自己高的列,则这个高度就是自己的高度。右边同样。

举个例子(参考题目当中的图片):

对于第一列,它的高为1,左边没有比它高的,则它左边的最高长度就是它自己1,它右边的最高高度是3,这一列的容量就是min(1,3)-1=0;

对于第二列,它的高度为0,它左边有比它高的列,高度为1,右边也有很多比它高的列,但我们选最高的那个,高度为3,综合选择两边较矮的那个,得其容量为min(1,3)-0=1;

对于第三列,它自身高度为2,它左边没有比它高的,则它左边的最高长度就是自己2,它右边的最高高度是3,这一列的容量就是min(2,3)-2=0;

我们可以用动态规划的方式,用两个动态规划数组分别记录下每一处位置左边比它高的最高高度,以及右边比它高的最高高度。

这两个数组初始化为0. 动态规划的转移方程也很简单:

记录左边最高高度的数组,从左往右生成,left_h[i]=max(left_h[i-1],height[i])

记录右边最高高度的数组,从右往左生成,right_h[i]=max(right_h[i+1],height[i])

代码:

class Solution(object):def trap(self, height):ss=0#总容量#每处(竖直)可容纳的雨水高度等于左右两边的比它高的柱子中,较矮的那个# 定义base case即可lenth = len(height)left_h=[0]*lenth# left_h[i]表示i位置左边的最大高度right_h=[0]*lenth#i位置右边的最大高度#base caseleft_h[0]=height[0]#最左边的左边最大高度就是自己 #以使得左右边界处会自己减成0right_h[-1]=height[-1]#最右边的右边最大高度也是自己#开始动态规划#计算左边最高高度的数组for i in range(1,lenth):left_h[i]=max(left_h[i-1],height[i])#计算右边最高高度的数组for i in range(lenth-2,-1,-1):right_h[i]=max(right_h[i+1],height[i])#开始正式计算for i in range(lenth):#每一列左右两边的(比自己高的)最大高度,取较小的那个与自身做差ss+=min(left_h[i],right_h[i])-height[i]return ss

小结:

注意对左右两边的处理,对于最左边的列,左边的最大高度是自己;对于最右边的列,右边的最大高度是自己。因为很显然它们左边或右边分别没有比自己高的列了,所以相应高度就是自己的高度。

总之这个题就是动态规划当中的经典问题了,要记住的是逐一对每一列求其容量。求容量的方法则是根据动态规划,对左右两边展开来求相应高度。

看懂理解后记住即可,不要钻牛角尖了。因为我不觉得有多少人能第一次看着个题就可以想出这种办法(起码我自己是),所以不要灰心,恭喜你又记住了一个套路,加油!。

LeetCode接雨水 动态规划相关推荐

  1. 【leetcode】【动态规划】股票买卖

    leetcode 股票买卖(动态规划) 这位大佬四种题型总结的很好:link 一共只有三种状态:买.卖.冷冻 buy[i]buy[i]buy[i] 表示第i天之前最后一次行为是buy时,最大的收益 s ...

  2. LeetCode Counting Bits(动态规划)

    问题:给出数字n,求0-n这些数的1的位数. 思路:方法一使用x&(x-1)统计数字1的位数. 方法二[0,1) [2,3)表示形式为[10,11) [4,8)表示形式为[100,101, 1 ...

  3. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串 22.4% 中等 10 正则表达式匹配 18.8% 困难 32 最长有效括号 23.3% 困难 44 通配符匹配 17.7% 困难 53 最 ...

  4. 【leetcode】【动态规划】最长回文子序列

    [leetcode]最长回文子序列 题目 代码 leetcode题目地址 题目 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度. 子序列定义为:不改变剩余字符顺序的情况下,删除某些 ...

  5. leetcode组队学习——动态规划

    文章目录 主要思想 模板步骤 例题 300. 最长上升子序列 674. 最长连续递增序列 5. 最长回文子串 516. 最长回文子序列 72. 编辑距离 198. 打家劫舍 213. 打家劫舍 II ...

  6. LeetCode.接雨水

    题外话:LeetCode上一个测试用例总是通不过(我在文章末贴出通不过的测试用例),给的原因是超出运行时间,我拿那个测试用例试了下2.037ms运行完.我自己强行给加了这句: if(second == ...

  7. Leetcode学习之动态规划

    动态规划学习内容 1. 动态规划理论基础 什么是动态规划 动态规划的解题步骤 动态规划应该如何debug 2. 斐波那契数 思路 3. 爬楼梯 思路 4. 使用最小关系爬楼梯 思路 5. 不同路径 思 ...

  8. leetcode42.接雨水 动态规划、双指针

    leetcode42.接雨水 题目描述 思路 动态规划: 雨水能存储多少,取决于较短的那一边的高度,所以我们可以列举出每一列左右两边最短的"木板",从而即可求解每一列最多存储多少雨 ...

  9. LeetCode Wiggle Subsequence(动态规划)

    问题:给出一个数组,求波动序列的最大长度. 思路:方法一使用up(i)表示第i个元素是上升时最大长度,down(i)表示第i个元素是下降时最大长度.则有up(i)=max(down(j) +1, up ...

最新文章

  1. 程序员的抱枕也太高大上了吧! | 每日趣闻
  2. C++Primer笔记-----day04
  3. [BZOJ1061][Noi2008]志愿者招募
  4. JAVA连接 mongodb(mac OSX)
  5. Linux系统中CPU使用率查询常用的5个命令
  6. typescript利用接口类型声明变量_TypeScript入门指南(基础篇)
  7. ubuntu16.04安装,使用redis布隆过滤器示例
  8. 判断是否遵守某个协议
  9. oracle 11g 配置navicate lite Instance Client下载
  10. 评选 cms_十大评选和编辑精选:12月评论
  11. 转:Java中子类是否可以继承父类的static变量和方法而呈现多态特性
  12. 滚蛋吧,2020的糟心事儿!2021,先“拼”为敬!
  13. 堪比科幻大片!优酷特效广告、互动视频技术大揭秘
  14. 黑苹果intel 9560ac网卡成功驱动,无需换卡
  15. word计算机板书,Word板书设计怎么写
  16. nginx做反向代理网站加载验证码图片不出来
  17. 【计算机网络】【应用层-5】
  18. macOS通过单个typeC拓展坞连接多台显示器实现多屏幕拓展(多屏异显)解决typeC拓展坞只能多屏镜像
  19. 关于手持设备PDA的开发
  20. matlab光学原理仿真应用衍射,基于Matlab的光学衍射仿真【参考】.doc

热门文章

  1. python字母转换_python中字母与ascii码的相互转换
  2. 论软件自动化测试中 QR_Code 的登录的逻辑
  3. (转帖)Redis的LRU和LFU区别
  4. React中实现插槽
  5. 我在工作群和ChatGPT聊了会天,找到了升职加薪的新思路
  6. 尚硅谷《全套Java、Android、HTML5前端视频》
  7. 苹果新专利曝光 背后有何暗示?
  8. 2022年8月及1-8月国内动力电池企业装车量排名:“宁王”第一,“迪王”猛追
  9. java或android国内外手机号码正则表达式
  10. 【创意生活】铅笔实景画,绝对创意