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

84 阅读2分钟

当青训营遇上码上掘金 针对于青训营主题四攒青豆,题目:

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

分析

结题的思路也是采用动态规划的思想,分为以下几种情况:

从前往后遍历数组; 如果当前高度高于上一个柱子高度,证明当前柱子的加入,可以继续加入豆子,导致最优解发生了变化,所以要更新前面柱子的高度。

这时候,再一次进行遍历;

寻找前面比当前柱子高的的柱子(可以把青豆挡住),找到后,更新寻找过程中遇到的柱子的高度较矮的柱子。 如果一直找到了初始位置,也没有找到,则说明当前柱子是前面所有柱子中最高的的。这时候说明当前填充高度,为最高的柱子,取开始和当前位置的较低点。

如果当前高度低于两边的高度,那么当前填充高度为左、右两个柱子中较短的高度。

存在问题

但是,注意上面标红的位置,这里是存在问题的!具体是什么问题呢?这种情况下求到的最低点不一定对于前面所有位置都是最低的。具体来看如下例子:

输入:[ 5, 2, 7, 4, 9] 分析:遍历到9的时候,由于9是最大的,因此会一直遍历到初始位置5,这时候程序认为从头到后最高的高度都是5,但是,比如倒数第二个位置,这里的填充高度应该是7,不是5,因此,就出现了错误。 输出:由于程序认为最后填充后的高度都是5,所以所以做差后求解结果为2。

正确思路

算法思路

正确思路十分简洁明了:

  1. 对于每一个位置,记录他左边最高的墙,记录他右边最高的墙。
  2. 二者取较小的就是能装的最高高度。
  3. 这两个数组的初始化通过两次遍历实现。(动态规划记录的过程,记录当前最大的)
  4. 最后求解的时候,遍历一遍实际的柱子,填充到左右两边较低柱子的高度。