我来攒青豆了 | 码上掘金

77 阅读2分钟

当青训营遇上码上掘金 如何解决攒青豆问题?

我们知道一个装水桶能装多少水取决于水桶得最短板。攒青豆也时类似,高度数组的长短也局限着攒青豆的数量。那如何通过高度数组计算出能攒多少个单位青豆呢?

最容易想到的办法就是使用模拟的方式遍历数组,即用双指针(l,r)来充当桶的两边,桶的宽度=r-l-1,两个指针能攒的青豆=宽度*MIN(height[l],height[r])。当r指针遍历完数组就可以计算出结果。

但是,本文并不使用上述方法解体。

单调栈

通过观察不难发现,当某一位置可以攒青豆时必然是高度先递减后递增的一个凹型。

image-20230203205053693.png

所以我们可以通过记录数组的单调来计算所能攒的青豆。

具体实现方式如下:

  • 首先,维护一个单调递减的栈
  • 其次,如果待入栈元素不大于栈顶元素时就直接入栈
  • 第三,如果栈顶元素小于待压栈元素,将栈顶元素弹出
  • 第四,计算栈顶元素到待入栈元素的可用空间并累加进结果
  • 第五,重复三四步,直到待入栈元素不大于栈顶元素或者栈为空,再将待入栈元素入栈
  • 第六,当遍历完高度数组,栈不为空时就可以出栈,计算剩余可用空间

图解单调栈

第一步: 将第一个元素入栈

image.png 第二步: 小于栈顶元素,入栈

image.png 第三步: 大于栈顶元素,出栈

image.png 第四步: 小于栈顶元素,入栈

image.png 第五步: 大于栈顶元素,出栈

image.png 第六步: 小于栈顶元素,入栈

image.png 第七步: 大于栈顶元素,出栈

image.png 第八步: 小于栈顶元素,入栈

image.png 第九步: 大于栈顶元素,出栈

image.png 第十步: 遍历数组,逐步弹出栈内元素,直到清空栈

image.png 以上就是单调栈解法图解,不会弄轮播图,观感不是很好。会的大佬教一下,感谢!

代码展示