当青训营遇上码上掘金
题目内容
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
解题思路
如图可知,下标为 i 的位置可以接到的青豆体积,取决于其左右两侧最高的柱子中较矮的那一个,且下标为 i 的位置的高度一定要小于其左右两侧最高的柱子的高度。
例如:下标为 2 的位置(下标从 0 开始)的高度为 2,其左侧最高的柱子的高度为 5,其右侧最高的柱子的高度为 4,易知,较矮的柱子的高度为 4,故,下标为 2 的位置所接青豆的体积为(4 - 2) * 1个单位(1 为柱子宽度)。
所以本题只需要将每个位置可以接到的青豆体积加在一起,就可以得出最终答案。
编写代码(Go语言版)
Step1: 首先用循环将每一个位置遍历一次,分别求出它们所接青豆得体积。此处用for循环即可,在循环体中求出对应位置所接的青豆体积。
for i := 0; i < len(height); i ++ {
// 求出该位置 i 所能接到得青豆体积
}
Step2: 找到位置 i 左右两侧最高的柱子,注意:位置 i 的高度必须要低于左右两侧最高的柱子。此处分别用for循环找到左右两侧最高的柱子。
temp := height[i] // temp 表示位置 i 的高度
// 找到左侧最高的柱子(不包括位置 i 的柱子)
maxL = temp // 由于位置 i 的高度必须要低于左右两侧最高的柱子
for j := 0; j < i; j ++ {
if height[j] > maxL {
maxL = height[j]
}
}
// 找到右侧最高的柱子(不包括位置 i 的柱子)
maxR = temp
for k := i + 1; k < len(height); k ++ {
if height[k] > maxR {
maxR = height[k]
}
}
Step3: 计算位置 i 所接青豆体积,并将其累加。
// 位置 i 的高度必须要低于左右两侧最高的柱子
if maxL != temp && maxR != temp {
// Go语言不支持三目运算符,即 c = a > b ? a : b
if maxL > maxR {
min = maxR
} else {
min = maxL
}
res += min - temp // 累加
}