当青训营遇上码上掘金
本次活动我选择的是主题四---攒青豆
一、题目分析
相信大家一看到这个问题就自然想到了木桶效应,想到木桶效应问题就已经解决一半了~
木桶效应:一只木桶能盛多少水,并不取决于最长的那块木板,而是取决于最短的那块木板。也可称为短板效应。
本次题目我们可以这样来理解,把这些柱子两个柱子为一组形成一个桶,题目就转化成了这些柱子能有多少个桶,构成桶的两个柱子是什么。
二、解决思路
很自然我们从左至右来找桶,而且我们只需要想出找第一个桶的方法,剩下的桶类比即可。
显然第一个柱子就是我们桶的左边界,所以我们只需要往右去找桶的右边界即可。
怎么去找右边界呢?
答:往右遍历木桶即可,若柱子比起始柱子高,我们就找到了,因为由于木桶效应再往后找就没有意义了,因为左边的柱子限制了青豆的数量;但是还存在一种可能,万一剩下的柱子没有比第一个柱子高的那怎么办呢?我们就选择剩下中最大的即可(就好像我们是从右往左找一样)。
看到评论说是接雨水,于是去leetcode搜了一下,并提交了一下,虽然效率很感人,但庆幸的是通过了...
三、代码
func zanqingdou(height []int) int {
n := len(height)
var nums int //青豆数量统计
var flag int // 记录下一根柱子的位置
var max int = -1 //记录剩下柱子中最大值
var i, j int
for i = 0; i < n; {
for j = i + 1; j < n; j++ {
//若发现存在柱子比边界柱子大自然退出,因为上限总是两边界柱子的最小值
if height[j] > height[i] {
flag = j
break
}
//记录剩下中最大位置
if height[j] > max {
max = height[j]
flag = j
}
}
//取边界中的最小者
var min int
if height[i] <= height[flag] {
min = height[i]
} else {
min = height[flag]
}
//统计这两根柱子之间的青豆,边界不计算
for w := i + 1; w < flag; w++ {
nums += min - height[w]
}
//更新柱子位置
i = flag
//初始化max
max = -1
//右边没有柱子,自然退出
if i == n-1 {
break
}
}
return nums
}