当青训营遇上码上掘金

720 阅读2分钟

当青训营遇上码上掘金

主题 4:攒青豆

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

image.png

1.当前列接豆子的量,取决于他的左右上界的最小值(双指针做法)
2.当前列接豆子的量,可以假设右侧上界无穷大,那么当前情况有一个值,假设左侧上界无穷大,又有一个解,两个解的最下值为真实值(可以作图理解)(DP做法)
3.利用对于凹槽的理解来进行接豆子,此处思路不同于单列接豆子量多少,而是直接思考一个凹槽能接多少水, 这个过程可以用单调栈模拟,维护单调减的栈,在i从左往右的过程中,如果有一个值比栈顶大,那么说明出现了凹槽,那么我们就可以找到这个凹槽的左右边界及上界,同时补平凹槽,继续往下执行。而单调栈模拟的就是这个凹槽的左侧部分,利用单调栈可以在 O(1)的时间找到与i值相对应的左凹槽壁的位置,这个过程就是单调栈的应用。
4.直观理解,也是找凹槽,对于每一个i找到与其对应的右边的凹槽,这个逻辑类似上面的单调栈的方法,但是找的过程中时间复杂度为O(n^2),过不了oj,如果需要过oj,可以先用单调队列跑一次全部数据,得到比当前位置大的第一个位置在哪里,这样就可以在 O(n)时间复杂度。
5.找高度数据中最大的,进行凹槽填补,逻辑还是填补凹槽,利用sort函数,对height进行排序,但是需要注意,排序cmp需要自写,因为最后我们得到的是一个下标的排序,排序的逻辑为heght[idx],最后从前往后选取两个最大的height进行填补,填补过程中,豆子和值变化点的同时,height数组也需要同时变化,避免出现该数据段被包含在其他数据段内,重复计数的情况。