当青训营遇上码上掘金
我选择的主题是第四个,数青豆
方便起见,这里放一下题面
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析: 输入:height = [5,0,2,1,4,0,1,0,3] 输出:17 解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
下面讲一下解题思路
首先我们要把撒青豆这一行为抽象一下,青豆是无数个,唯一的限制只有柱子的高度,那么我们就可以把青豆想象成水,把柱子想象成木桶,用木桶和水的视角代入,再来看一下这道题,
输入是一组木桶的底板高度,现在把一桶足够多的水往木桶上倒,问静止后的木桶里有多少体积的水
既然提到了木桶和水,一定会联想到木桶效应吧
木桶定律是讲一只水桶能装多少水取决于它最短的那块木板。
仔细一想就会发现,每块底板上面水的高度,是不是就是取决于它两边桶的边缘的最低板的高度,什么是桶的边缘呢,从抽象的角度来看,桶的边缘就是指两边最高的底板的高度,这样就形成了一个类似桶的结构,但是这只是考虑了一块底板的角度,还有其他底板,当然其他底板也是一样的道理,上面水的高度都是取决于两边最高的底板的最低高度,最后把所有底板都遍历一遍就获得了全部的水的体积。
总结之后的思路来了,我们需要知道每块底板的左边和右边最高高度的高度各是多少,然后上面水的高度就是左右的最小值减去当前板块的高度,那么我们怎么求出左右两边的最高高度是多少呢?
最暴力的想,我们直接枚举,第x个的左边最高就是包括x在内的左边所有高度中最高的,这样的时间复杂度是O(n^2),那能不能优化一下呢,因为是从左往右的,所有可以优化一下求最大值的过程,求前x个中的最大值可以转化成求前x-1个中的最大值和第x个的最大值是多少,那么这时候时间复杂度就可以优化到O(n)了
下面放上代码来讲,用的语言是 python,代码在 script 页,由于用的不是前端代码,而且码上掘金不支持使用 python,所以没法在码上掘金测试,程序是对的
代码思路就是根据上面说的思路来,首先初始化一下左最高和右最高数组,分别用于存放第x个的右边和左边的最高高度是多少,再分别从左往右和从右往左遍历获取高度,最后我们只需要枚举一下,取最小值减去当前高度就是当前柱子的贡献了,把总贡献统计起来就是我们需要求的答案了