当青训营遇上码上掘金

52 阅读2分钟

题目

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

双指针解法

由于不考虑边角堆积,所以两端是不计入的。遍历每一列,将每一列可以放的青豆数进行求和就可以得到答案,而每一列可以存放的青豆数等于这一列左右两边各自最高位的最小值减去这一列本身的高度。
在每次遍历的过程中,需要向两边寻找最高的列,所以时间复杂度位O(n^2),空间复杂度为O(1)

动态规划解法

从前面的分析不难总结到 当前列青豆数=min(左边列的最高高度,右边列的最高高度) - 当前列高度。前面的双指针的解法在计算左边列和右边列的最高高度在遍历的过程中的求解有重复。而这两个值的求解可以使用动态规划
当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。
即从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);
从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);
我们首先用两个数组求解出每一列左边的最高高度和右边的最高高度

单调栈解法

单调栈是一种保存栈内元素有序的算法(之所以说是算法是因为我们只是使用了栈这种数据结构,有序这种通过我们的程序来保证)
我们在保证单调栈的过程中,一旦发现想要加入单调栈的数值大于栈顶元素,就说明出现了凹槽(栈顶元素为凹底),栈顶的下面的元素代表的是凹槽左边的柱子,预添加的元素就是凹槽右边的柱子。
单调栈内维护的是列数,这样我们就可以比较轻松的计算凹槽的面积即青豆数