当青训营遇上码上掘金
-
题目:攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
思路解析
第一次看这个题,我以为是将各个高度的数组数据之和相加,当相加完以后发现数组之和为16,和输出不相符。然后我在分析发现豆子在黑色容器的中间,那这就跟水桶一样,黑色柱子组成容器,装多少水全看短板,那这个图为两个容器5-4和4-3,总共攒青豆为17。
现在开始从左往右开始遍历数组,第一个和最后一个数组数据不可能是0,即从1开始到len-1;
i=1时,当前高度为0,左边最高为5,右侧最高为4,则当前位置能装青豆4-0=4个
i=2时,当前高度为2,左边最高为5,右侧最高为4,则当前位置能装青豆4-2=2个
i=3时,当前高度为1,左边最高为5,右侧最高为4,则当前位置能装青豆4-1=3个
i=4时,当前高度为4,左边最高为5,右侧最高为4,则当前位置能装青豆4-4=0个
i=5时,当前高度为0,左边最高为4,右侧最高为3,则当前位置能装青豆3-0=3个
i=6时,当前高度为1,左边最高为4,右侧最高为3,则当前位置能装青豆3-1=2个
i=7时,当前高度为0,左边最高为4,右侧最高为3,则当前位置能装青豆3-0=3个
总共17粒豆子
实现过程中如何确定当前位置左侧和右侧数组的最大高度func leftmax(array []int) int {
max := array[0]
for i := range array {
if array[i] > max {
max = array[i]
}
}
return max
}
func rightmax(array []int) int {
max := array[0]
for i := range array {
if array[i] > max {
max = array[i]
}
}
return max
}
代码实现:
func qingdou(array []int) int {
count := 0
for i := 1; i < len(array); i++ {
h := array[i]
left := array[:i]
left_max := leftmax(left)
right := array[i:]
righ_max := rightmax(right)
if left_max < righ_max {
count = count + left_max - h
} else {
count = count + righ_max - h
}
}
return count
}
[具体的代码实现请看](攒青豆 - 码上掘金 (juejin.cn))