攒攒攒攒青豆 | 「青训营 X 码上掘金」主题创作

60 阅读2分钟

当青训营遇上码上掘金

题目介绍

主题4:攒青豆

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

image.png

以下为上图例子的解析: 输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

题目分析

常刷leetcode的应该都见过与这道题目及其相似的“接雨水”题。我当时初见便是使用的双指针方式来进行解决。后来复盘时也学到了其他三种方法,分别是动态规划,栈和线性扫描。在这里我将我使用的双指针方法与单调栈的方法进行简单介绍并附上代码

实现思路

双指针

image.png 在这里我以例图加以说明方法。首先是两个指针指向的“柱子”,有两种情况。

  1. 假设某一时刻指针分别指向0和4,即高度为5的柱子与高度为4的柱子。在两个指针之间没有比“短柱”即高度为4的柱子高的柱子,那么能接到的青豆只需要减去两个指针之间的柱子所占的高度即可
  2. 假设某一时刻指针指向0和end,即高度为5的柱子与高度为3的柱子。我们所需要增加计算因为加入了高度为4的柱子之后增加的面积。我们可以在计算完后,将“地平面”高度升到3,这样就可以回归到情况1. 这样就可以通过双指针方法计算出接住的青豆。

单调栈

维护一个单调栈。单调栈存储的是下标,满足从栈底到栈顶的下标对应的数组heightheight中的元素是单调递减的。在这里摘录一段来自于leetcode的图片加以说明,个人认为以图片说明更能方便于理解。图片作者为Ikaruga

560d6232993961a9e95608595013064712e9b7ea769a20175ae68b7fa9510041-图片.png

9f74f1cf461b56d9c2cf016674190211319faeead9c7ff919a9bddda43131272-图片.png

b54d427eb60369785e90d5977ba3306559f4049f5fcb9c04f7c1e14126bd9669-图片.png

1ffffe08addd5b96cdc4a7b6b8104e689946ba877defd2ff34a342e0347c33c5-图片.png

0e1a9e0f7842b21ddf191979907dc4979e3c9160dbac3d722430e9a87c1e5e35-图片.png

55c4e22da1a632c8dcf4ed278c906899ebbcb58bf66982a488903ef3355fbab4-图片.png

代码片段