主题4:攒青豆

76 阅读2分钟

当青训营遇上码上掘金

参考文章:「青训营 X 码上掘金」主题 4——攒青豆

题目内容

攒青豆.png

以下为上图例子的解析: 
输入: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  // 累加
}

掘金代码