当青训营遇上码上掘金 如何解决攒青豆问题?
我们知道一个装水桶能装多少水取决于水桶得最短板。攒青豆也时类似,高度数组的长短也局限着攒青豆的数量。那如何通过高度数组计算出能攒多少个单位青豆呢?
最容易想到的办法就是使用模拟的方式遍历数组,即用双指针(l,r)来充当桶的两边,桶的宽度=r-l-1,两个指针能攒的青豆=宽度*MIN(height[l],height[r])。当r指针遍历完数组就可以计算出结果。
但是,本文并不使用上述方法解体。
单调栈
通过观察不难发现,当某一位置可以攒青豆时必然是高度先递减后递增的一个凹型。
所以我们可以通过记录数组的单调来计算所能攒的青豆。
具体实现方式如下:
- 首先,维护一个单调递减的栈
- 其次,如果待入栈元素不大于栈顶元素时就直接入栈
- 第三,如果栈顶元素小于待压栈元素,将栈顶元素弹出
- 第四,计算栈顶元素到待入栈元素的可用空间并累加进结果
- 第五,重复三四步,直到待入栈元素不大于栈顶元素或者栈为空,再将待入栈元素入栈
- 第六,当遍历完高度数组,栈不为空时就可以出栈,计算剩余可用空间
图解单调栈
第一步: 将第一个元素入栈
第二步: 小于栈顶元素,入栈
第三步: 大于栈顶元素,出栈
第四步: 小于栈顶元素,入栈
第五步: 大于栈顶元素,出栈
第六步: 小于栈顶元素,入栈
第七步: 大于栈顶元素,出栈
第八步: 小于栈顶元素,入栈
第九步: 大于栈顶元素,出栈
第十步: 遍历数组,逐步弹出栈内元素,直到清空栈