当青训营遇上码上掘金
主题介绍(题目介绍)
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
分析:
这个题目好像力扣的某一个题目,具体的名字我忘记了。好像是接雨水?
上面掘金给出的图片解析非常的形象生动,这个青豆是哪个运营想出来的?
可以看出这个题目是有关于木桶效应。木桶能装多少水取决于最短的板子而不是最长的板子。所以应该先算出两侧最短的长度
任意一个位置,只要你知道该位置的左边界和右边界就知道这个位置能装多少豆了。
模拟思路
如题目所示:(从左到右遍历)
[5,0,2,1,4,0,1,0,3]
第一步:5是柱子,不统计
第二步:0表示没有,右边最大的值为4,4-0=4
第三步:2,右边最大的值为4 小于左边最大的值5 4-2=2
第四步:1,左右边最大值的较小值为4 4-1=3
第五步:4 左右最大值的最小值为4 (即是自己)4-4=0
第六步:0 左右边最大值的较小值为3 3-0=3
第七步:1 左右边最大值的较小值为3 3-1=2
第八步: 0 左右边最大值的较小值为3 3-0=3
第九步:3 柱子,不统计
最后将其总数相加 4+2+3+0+3+2+3 = 17
以此类推,遍历整个数组就可以得出整个数组能接到多少青豆了。
代码思路
首先创建相关的变量
遍历不包含首尾的数组,创建一个计算左右最大值的函数,在遍历的同时每次都调用这个函数。并保存这两个的值(go的多参数返回真好用),最后比较两个值的大小,用当前遍历的值减去两者的小值,最后再将其加上总数即可。
注意的地方:
- 两侧的数值不计入统计
- 注意函数中的i和数组的index越界问题
如果代码或者思路有错误,请指出。感激!
总代码:
package main
import "fmt"
func main() {
// 定义总豆子
var total int = 0
// 定义示例数组
var beans = []int{5, 0, 2, 1, 4, 0, 1, 0, 3}
// 传入函数
total = calcTotal(beans)
fmt.Println(total)
}
func calcTotal(beans []int) int {
total := 0
//left := 0
right := len(beans)
// 只有两个或者一个的情况下
if right == 1 || right == 2 {
return 0
}
//leftMax := 0
//rightMax := 0
for i, value := range beans {
leftMax, rightMax := calcMax(beans, i)
// 最左侧和最右侧 为柱子,不可取
if i == 0 || i == right-1 {
continue
}
// 左小右大
if leftMax < rightMax {
total+=leftMax-value
}else {
total+=rightMax-value
}
fmt.Printf("第%d个元素 左最大值:%d 右最大值:%d 总豆子数:%d \n",i,leftMax,rightMax,total)
}
return total
}
// 计算左侧和右侧的最大值
func calcMax(beans []int, i int) (int, int) {
//temp := i
left := i
right := i
leftMax := 0
rightMax := 0
// 两次遍历
for left >= 0 {
//leftMax=leftMax>beans[left]? 什么残废语言不支持三元运算符
if leftMax < beans[left] {
leftMax = beans[left]
}
left -= 1
}
for right < len(beans) {
//leftMax=leftMax>beans[left]?
if rightMax < beans[right] {
rightMax = beans[right]
}
right += 1
}
return leftMax, rightMax
}
运行结果
- 第1个元素 左最大值:5 右最大值:4 总豆子数:4
- 第2个元素 左最大值:5 右最大值:4 总豆子数:6
- 第3个元素 左最大值:5 右最大值:4 总豆子数:9
- 第4个元素 左最大值:5 右最大值:4 总豆子数:9
- 第5个元素 左最大值:5 右最大值:3 总豆子数:12
- 第6个元素 左最大值:5 右最大值:3 总豆子数:14
- 第7个元素 左最大值:5 右最大值:3 总豆子数:17
- 17