当青训营遇上码上掘金
码上掘金
题目:
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
思路:
柱面height[]从第一个height[0]开始,直到下一个最大高度height[i]的柱面,青豆数目就是在这两个之间数出来,接下来就是分析这个柱面怎么产生的。(青训营给的示例是剩余的柱面高度都是小于第一个的,但为了全面点,应该考虑柱面大于的情况。)
下一个柱面height[i],应是除了第一个柱面外最高的。接着讨论:如果柱面高度height[i]>第一个柱面高度height[0],那么选择的基准水平面就是height[0];反之选择height[i]高度为基准水平面。即在两个最高的柱面间选择较低的。
然后以此类推,以height【】为新的height【0】,接着找下一个最大高度height【】,直到最后一个柱面结束。
总的要点:1找到最高柱面的位置;2计算两个柱面间的青豆数,直到最后的柱面
第一点是一个查找,找最大值;第二点是一个简单的计算,且是持续向后叠加的过程,只需遍历一次原数组,Go的切片比数组灵活性大,且可以通过切片表达式,实现逻辑;切片是引用类型,复用切片底层数组不变。
代码如下
package main
import (
"fmt"
)
func maxloc(a []int)int{
flag:=a[1]
loc:=int(0)
for i:=0;i<len(a);i++{
if(flag<a[i]){
flag=a[i]
loc=i
}
}
return loc
}
func main(){
var height=make([]int,0,10)
height=append(height,5,0,2,1,4,0,1,0,3)
loc:=maxloc(height)
sum:=0
for {
for i:=0;i<loc;i++{
sum+=height[loc]-height[i]
}
if len(height)!=loc+1{
height=height[loc+1:]
loc=maxloc(height)
}else{ break}
}
fmt.Printf("青豆的总数是:%d",sum)
}