当青训营遇上码上掘金

58 阅读2分钟

当青训营遇上码上掘金
此处完成的是主题四的创作,由于本题解法较多,这里只采用了一种直观简洁的方法,如有雷同,望谅解。

题目

该主题是一道算法题,题目如下:

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

以下为上图例子的解析:

输入:height = [5,0,2,1,4,0,1,0,3]

输出:17

解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

image.png

思路及解法

直观地,每个小柱子所盛的豆子由本身的高度以及左右的最高柱子决定。问题的本身是求最终可以接到的青豆有多少,对于该问题,我们可以着眼于数组中每一根柱子的高度,本柱子上可以堆积多少青豆,取决于其左边最高柱子以及右边最高柱子,根据木桶效应,我们会选择其左边柱子以及右边柱子最低的那一个即可。
采用双指针,“按列计算”,每个柱子的宽度都是1,只要维护高度即可。

  • 维护两个指针 l 和 r ,以及两个变量 max_lmax_lmax_l 和 max_rmax_rmax_r。lll 从左往右移动,rrr 从右往左移动,同时更新 max_lmax_lmax_l 和 max_rmax_rmax_r,直至指针相遇。

  • 没有相遇时,做如下:

    • max_l = max(max_l, height[l]), max_r = max(max_r, height[r])
    • 如果 max_l < max_r,则 (max_l - height[l])*1 是当前柱子的青豆数目,lll 右移;rrr 同理
  • 当两个指针相遇时,即可得到能接的青豆总数。

当然,本题也可以用动态规划,贪心等思路做出,此处不再过多赘述。

  • 时间复杂度:O(N),其中 N 是height的长度
  • 空间复杂度:O(1)

源代码