当青训营遇上码上掘金 主题4 攒青豆

55 阅读2分钟

当青训营遇上码上掘金。

主题4:攒青豆

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

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

输出:17

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

思路

尝试进行作图,找出可能出现的各种情况。 2.png 按列来看,每一列能接住的高度可以不断向上增长,直到与它两侧各自最高的柱子中较低的那个相平为止。

从图上看,可以从较低的一侧向另一侧作水平线,水平线以下的部分就是能接住的部分。

为了得出每一列的高度上限,可以使用两个指针分别从两端出发,每次取较低的那个向内侧作水平线,计算经过的每一列的结果,直到遇到高度相等或更高的柱子而停止。移动指针后继续进行,直到两个指针相遇,即可得出最终结果。

这种算法,每一列只会计算一次,所以时间复杂度是O(N)。只需要存储所有柱子的高度和几个临时变量,所以空间复杂度也是O(N)。

代码

根据思路,使用Go语言编写代码。 height为输入柱子高度的数组,i和j分别为左右两端的指针,k为作水平线时移动的指针,a为计算结果。

左右两端指针未相遇即继续循环。每次循环比较两个指针处的高度,从较低的那个向内作水平线,依次计算经过的每一列的结果,并累加到最终结果上,直到遇到相等或高于水平线的柱子而停止,然后指针移到该处,完成本次循环。

最后循环结束,输出最终结果。