当青训营遇上码上掘金让我疯狂攒青豆思路与实现

48 阅读2分钟

当青训营遇上码上掘金

babdc4fe29cc6ac6b1e91aa5a282766.png

  • 题目:攒青豆

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

攒青豆.png

以下为上图例子的解析:

输入: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))