当青训营遇上码上掘金
主题 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 个单位的青豆。
先上我的代码:

思路解析:以题例数组为例
在LeetCode上可以看到类似题目——接雨水,同样借鉴木桶效应,这一方法的基本思想在于,任一位置的青豆数取决于其左右最高柱子的较小者,
本题同样也是该思路,能装多少青豆,取决于这个地方左右两侧的高度的较小者,以及这个地方的高度,两者的差值就是能装青豆的数量。每个地方的高度我们已经知道,我们可以从数组左边和数组右边分别遍历,取得最大值,然后两者之间的较小的那个,就是我们需要的左右最高柱子的较小者,然后减去当前高度即可。最终值应为:
min{左边最高柱子高度,右边最高柱子高度} - 该位置柱子高度
在getCode方法中,创建两个切片和两个for循环,第一个切片存放每个位置左边的柱子最大高度,从左向右遍历比较得到;第二个切片存放每个位置右边的柱子最大高度,从右向左遍历比较得到;
maxBegin := make([]int, l) //每个位置左边的柱子最大高度
maxBegin[0] = height[0]
for i := 1; i < l; i++ {
if height[i] > maxBegin[i-1] {
maxBegin[i] = height[i]
} else {
maxBegin[i] = maxBegin[i-1]
}
}
for循环后maxBegin = {5,5,5,5,5,5,5,5,5}
maxEnd := make([]int, l)
maxEnd[l-1] = height[l-1]
for i := l - 2; i >= 0; i-- {
if height[i] > maxEnd[i+1] {
maxEnd[i] = height[i]
} else {
maxEnd[i] = maxEnd[i+1]
}
}
for循环后maxEnd = {5,4,4,4,4,3,3,3,3},两个数组的值即为每个位置左右柱子的最大高度
得到每个位置左右柱子的最大高度以后,最后一个for循环比较每个位置左右柱子的最大高度的较小的那个,再减去当前位置的高度,即可得到每个位置的青豆数,再进行累加即可得到最终值17返回即可:
for i := 0; i < l; i++ {
if maxEnd[i]-height[i] < maxBegin[i] {
n += maxEnd[i] - height[i]
} else {
n += maxBegin[i]
}
}
return n