当青训营遇上码上掘金

444 阅读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_rmax\_rll 从左往右移动,rr 从右往左移动,同时更新 max_lmax\_lmax_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 是当前柱子的青豆数目,ll 右移;rr 同理
  • 当两个指针相遇时,即可得到能接的雨水总量。

代码

代码由本人创作于码上掘金平台,点击运行,可在线查看运行结果

复杂度分析

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

写在后面

其实,这里还可以考虑使用单调栈来求解。

单调栈,即栈内元素保持有序的栈,典型的应用场景是:数组中求比当前元素大/小的最近元素(位置)

References

oiwiki