当青训营遇上码上掘金
先上代码
介绍一下题目
攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
说明
这题是Leetcode上面应景的题,对应的地址是42. 接雨水 - 力扣(Leetcode),也就是常说的LeetCode上面的接雨水问题。
接雨水问题是一个很有趣的问题。读的过程中有点像是木桶原理的问题,也就是说承装不管是雨水还是豆子还是什么奇奇怪怪的玩意,都是类似一个筒子的结构,左右两边决定了他能装多少。
那下面就需要分析一下有大概几种情况了: 1.左/右漏下去 2.平底 3.不平底 这样分析,能看出来能够承接东西的特点在:其高度一定是先大再小再大的(不算废话)
这里用到了一个“单调栈”的方案,思路也是来自代码随想录 所谓的单调栈实际上是一个保证栈内元素按照“从小到大”/“从大到小”的顺序安排的一个栈,也就是一个人为安排的一个特殊顺序栈,那它具有的好处如下: 1.能够随时获得所需要的最大/最小值 2.同时保证历史上最大/最小值变迁的记录 那么对于接东西应该采取的顺序应该是从栈顶到栈底是从小到大的顺序。 因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。 遇到相同元素的时候,应当弹出栈顶元素,再新加入一个元素,完成元素的迭代。
这样每个元素都会经过单调栈的评价,如果小于已有的栈顶,证明可以作为新的容器顶部,如果等于已有栈顶,证明可以一并处理,如果大于栈顶,证明这是一段上坡,该存水了
下一个问题是栈存什么,直接的想法是存高度,但是高度本身就是一个数组,也就是随时可以获取的部分,并且对于容量的计算实际上需要进行一个成分,也就是面积,也就是 长 * 宽 那么随时可以获得宽度(也就是高度)的时候,需要保存的内容就是长度,而长度就是数组下标的差,以此得到可以储存下标。
按照这样的逻辑遍历就能解决问题了。 细节就是如上的代码。