攒青豆 | 「青训营 X 码上掘金」主题创作

71 阅读2分钟

当青训营遇上码上掘金

主题介绍

  • 主题 4:攒青豆

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

    描述图

以下为上图例子的解析:

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

解决思路

其实这是一个相当经典的题目接雨水的变体。可以有多种方法解决,这里我采用自然而然想到的一个思路:“单调栈”解决。

单调栈是基于栈的一种线性数据结构,其需要满足栈内元素单调递增或单调递减。

实现代码

维护一个单调栈储存高度数组的下标i。满足栈中元素从栈底到栈顶height[i]递减。

从左到右遍历数组,当当前的高度height[i]大于栈顶元素的高度height[top]时,即存在能攒到青豆的空间。(值得注意的是,栈中至少要有两个元素。栈顶元素出栈后的栈顶元素高度为height[left])高度为min(height[i], height[left]) - top,宽度为i - left - 1

遍历结束后则得到能攒到的青豆总数。

由于码上掘金与leetcode等网站的输入输出方式有所不同。故需要点击script Tab,并点击运行。之后按F12,在devtools中能看到答案。输入的更改则可更改testCase变量中的数组。

后记

聪明的小伙子应该意识到栈空间其实是可以优化为两个指针。该任务也能通过双指针解决,除此以外,也有动态规划的解决方法,但空间复杂度并非最优。

`