当青训营遇上码上掘金
题目描述
-
攒青豆
现有 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>1过,0<1攒一颗青豆,2>1过,1=1过,4>1过,0<1攒一颗青豆,1=1过,0<1攒一颗青豆,3>1过。
可以发现,在第i层,当遇到大于i的柱子之后,大于等于i的不攒青豆,小于i的攒一颗青豆,i的变化范围是1-数组中最大值。
我们可以维护一个boolon值start,用来表示是否遇到大于i的柱子,然后维护一个temp,在遇到小于i的柱子时加一,而遇到大于i的柱子时就可以把temp的值加到最终答案res里,并清空temp。
进行遍历就可以查出青豆的数量。
代码
from typing import List
def main(nums: List[int]) -> None:
mh=max(nums)
# print(mh)
res=0
for h in range(1,mh):
temp=0
start=False
for n in nums:
if n>=h:
start=True
res+=temp
temp=0
if n<h and start:
temp+=1
print(res)
if __name__ == '__main__':
main([5,0,2,1,4,0,1,0,3])
main([0,1,0,2,1,0,1,3,2,1,2,1])
main([4,2,0,3,2,5])
运行结果
17 6 9
总结
掘金代码组件没有包含List库,需要手动导入。
除此以外这道题还可以用动态规划,找到当前柱子左右最大的柱子高度,或者栈,如果遍历到栈顶对应高度的柱子pop并计算当前累计青豆数,或者双指针。
如果解题分析和代码结果有疑问,可以在评论区发表观点,我会及时回复的。