「青训营 X 码上掘金」第四题

57 阅读2分钟

当青训营遇上码上掘金

题目描述

  • 攒青豆

    现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

攒青豆.png

以下为上图例子的解析:

输入: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并计算当前累计青豆数,或者双指针。
如果解题分析和代码结果有疑问,可以在评论区发表观点,我会及时回复的。