当青训营遇上码上掘金
主题 4:攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
这个题目是非常有意思的,类似于竹筒效应,因为不需要考虑边角堆积问题,所以一个单位就是一个青豆。
方法一:其实看图很容易看出来,以4为分界线,左边能乘多少青豆取决于4的高度,右边则取决于3的高度。那么按照数学的想法来看,左边的总数目就是34-(1+2)=9个,加上右边33-1=8个,总共17个。这样的思路没有任何毛病,但是运行到代码上那可能是需要下点功夫,单纯考虑遍历就得嵌套两次,时间复杂度就会大大上升,所以这个方法不太好。
方法二:从左到右逐一去遍历。其实按照遍历的思维,这个图也不难看得出来从下标为1的地方开始遍历,因为两头的3和5都是边缘,不需要去考虑遍历他们,因为这两个位置根本不可能放青豆。
下标为1的地方,左侧最大数为5,右侧为4,那么1的位置就放4-0个豆。
下标为2的地方,左侧最大数为5,右侧为4,那么2的位置就放4-2个豆。
下标为3的地方,左侧最大数为5,右侧为4,那么3的位置就放4-1个豆。
下标为4的地方,左侧最大数为5,右侧为4,那么4的位置就放4-4个豆。
.............
按照这个规律,我们不难发现,这个遍历起来比第一次的方法要好一点,代码量也会少一点。
下面是我简单写的一个关于攒青豆的java代码,如果有写的不好的地方,还请大佬多多指点。