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. 那些对程序员来说伤害性不高但是侮辱性极强的瞬间…
  3. 标记meta http-equiv = X-UA-Compatible content = IE=edge,chrome=1
  4. java9新特性-16-Deprecated的相关API
  5. 第四周作业 wcPro
  6. MySQL设置表的字符编码为utf-8
  7. SAP Spartacus Delivery Mode Component单元测试的Mock设计图
  8. java nio is例子,Java Buffer isDirect()用法及代码示例
  9. scope python_Python标准库Scope
  10. java ext pagesize_更改透明图像的不透明度/更改extgstate字典的值
  11. 注册、注销与结束session变量
  12. 开会坐在后面,意思是不感兴趣
  13. 怎样修改计算机系统8,win8改win7,教您win8怎么改为win7系统
  14. SVN检出项目到本地
  15. 服务器虚拟机解锁苹果,Unlocker(VMware虚拟机MacOS系统解锁工具)v3.0.2 免费版-ucbug软件站...
  16. HDB3码:快速上手步骤实例
  17. EPLAN中如何画屏蔽双绞线
  18. 周爱民-javascript
  19. 自封装验证手机号码、邮箱格式、身份证号的工具
  20. 对数の学习笔记(一)

热门文章

  1. 小帅哥~小美女~快点进来看看内部类鸭~
  2. 今日新闻简报 十二条微语早报 每天一分钟 知晓天下事 3月2日
  3. 自动化测试和软件测试的区别,自动化测试和手动测试之间的区别
  4. 锐龙r76800h和酷睿i512500h核显对比 r7 6800h和i5 12500h哪个好
  5. web_socket 协同文档编辑
  6. 关于ca以及证书颁发的一些事
  7. Aspose.Slides使用教程:使用 C# 在 PowerPoint 演示文稿中添加页眉和页脚
  8. JS-修改图片颜色值
  9. Golang语言快速上手到综合实战视频教程
  10. android之媒体硬解OMX的实现