当青训营遇上码上掘金
主题4:攒青豆
题目: 现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
解决思路:
这道题可以使用(暴力)模拟的方法解决。
暴力模拟是容易想到的思路,只需要根据题意模拟即可。
要使用模拟的方法,首先需要排除两边的柱子,因为两边的柱子只有一侧,是接不到青豆的。
排除了两边的柱子之后,分析问题,发现较小的柱子高度能决定接多少青豆,(类似于木桶效应),所以,解决问题的核心思路是:首先,依次遍历每一个柱子,然后对每一个柱子完成“查找其左边最高的柱子”和“查找其右边最高的柱子”的操作,然后针对获得的这两边最高的柱子取较小的那一个,并与当前柱子的高度比较,最后再减去当前所遍历的柱子本身的高度,从而得出当前柱子可以接到的青豆,将其加入到答案中。在外层循环遍历结束后,即可得到可以接到的青豆数量,即为题目答案。
时空复杂度分析:
时间复杂度:
遍历除了边缘的柱子以外的所有柱子:O(n)
左右遍历最大值:O(n)
总体时间复杂度:O(n^2)
空间复杂度:O(1)
本题其他解法:
暴力模拟的解法比较简单,但空间复杂度比较高,数据量较大时会超时,这是一道经典的算法题目,由于本活动题目对此没有要求,使用简单的暴力模拟思路来解决问题即可。本题还可以使用双指针、单调栈、动态规划等方法解决。暴力模拟的思路是该题解法的基本思路,但后续仍然需要能够利用这些方法,降低时间复杂度,使题目解法能满足时间复杂度的要求。