计算青豆数量

160 阅读2分钟

当青训营遇上码上掘金

算法题:攒豆子

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

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

Screenshot 2023-01-13 at 17.29.30.png

初看这题是比较懵的,能否积攒豆子要根据左右柱子的高度所决定.

最初的思路就是计算出每个位置积攒的豆子,最后加在一起,但问题的难点就是怎么判断该位置能否接住豆子以及如何计算出每个位置的豆子数量.

  • 通过观察我们发现.一个位置要能积攒豆子的条件是 该柱子左右两侧柱子的高度要大于该位置,知道了该位置能否积攒豆子后,那如何计算出该位置的豆子数量呢?我们应该都知道木桶效应(木桶是储水量取决于短板),那么位置i处的豆子数量应为:i左侧最高的柱子与i右侧最高的柱子取两者中的最小值-i位置处的高度.

每次计算i位置的豆子数量都要进行一次扫描前后柱子的最大高度,这样做时间复杂度会变高O(N2),我们可以先左右各扫描一次,计算出每个位置左右柱子的最大值,保存在两个数组中. 然后遍历该数组,对比出最小值,用它减去该位置柱子的高度就是攒豆子的数量啦

  1. 我们先从左边向右边扫,找出每个位置i左边的距离自己最近的最大值,得到数组[5,5,5,5,5,5,5,5,5,5] 如图:

Screenshot 2023-01-13 at 17.30.56.png

  1. 我们再从右边向左边扫,找出每个位置i右边的距离自己最近的最大值,得到数组[5,4,4,4,4,3,3,3,3]

Screenshot 2023-01-13 at 17.29.57.png

最后我们将这两张图叠放在一起,取并集部分就是豆子的数量

Screenshot 2023-01-13 at 17.29.45.png

Talk is cheap,show me your code!