当青训营遇上码上掘金
-
题目:攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
-
解析:
看到题目我们首先考虑一个问题假设我们只有三根柱子那么只有中间的那根柱子能够接到青豆,总共能接多少青豆相当于问我们中间柱子上面可以放多少青豆。而中间柱子上面能放多少青豆,取决于中间柱子两边的柱子的高度和中间柱子的差值。那么问题就转化为求中间柱子两边的柱子的高度和中间柱子的差值,而这个差值的大小则取决于两边柱子高度较小的那根柱子。这样就取得了中间柱子能接住的青豆数量也三根柱子能接到的青豆数量。然后我们将这个问题进行拓展到一排柱子,求当前柱子可以接住多少青豆相应的则变为了当前柱子和所有左边柱子的最大值以及右边所有柱子的最大值两者中的较小值之间的差值,即为min(左边所有柱子的最大值,右边所有柱子的最大值)-当前柱子的高度。求得了一个柱子的能接到青豆的数量,则依次类推进行可以求出结果。
-
算法过程:
需要注意的是:在求柱子左边柱子最大值和当前柱子右边最大值的时候,需要将所有柱子左边柱子最大值和右边柱子最大值初始化为0,这样方便进行计算。为了方便进行展示代码结果,本文直接将例子输入代码进行结果展示。也可以自行输入,但需要写输入输出函数。
-
python代码:
def main(height):
n=len(height)
left=[0]*n
right=[0]*n
leftmax=0
rightmax=0
for i in range(n):
if leftmax<height[i]:
leftmax=height[i]
left[i]=leftmax
for j in range(n-1,-1,-1):
if rightmax<height[j]:
rightmax=height[j]
right[j]=rightmax
ans=0
for i in range(n):
ans+=min(left[i],right[i])-height[i]
print(ans)
-
代码运行:
-
总结:
本文仅写出了使用左右遍历进行解决该问题的思路,解决该题还有其他思路,例如:可以使用双指针进行解决。