当青训营遇上码上掘金 - 攒青豆
题目描述
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
详解
本题与 leetcode 42.接雨水完全一致。下面用双指针简述:
- 如果当前节点的高度小于左右其两侧的最大值,则可以接到雨水。
- 如何获取到对于当前节点而言的左右两侧的最大值,可以考虑采用“预处理”的办法,即先从左往右遍历,求出对于当前节点而言的左侧最大值,相同原理求出右侧最大值即可。
代码示例
时间、空间复杂度
对于预处理的方式,我们需要分析其时间复杂度。根据代码,我们可以知道只需要从左往右遍历一遍我们便可知道对于每一个位置,其左边的最高值是多少,显然时间复杂度是 O(n) ;当然,对于对称的从右往左遍历,其时间复杂度如上。
除了预处理部分的时间复杂度,我们还需要处理在主体函数的时间复杂度。当然,在这题中我们可以发现,当已知对于每一个位置的左边最高值和右边最高值的时候,就可以求出当前可以存储多高的青豆。因此时间复杂度就是 O(n) 。当然,这种解法的空间复杂度是 O(n) ,因为我们需要每个位置的左边的最高值和右边的最高值,因此我们需要用数组去缓存改值。
当然,我们可以选择去优化这一时间复杂度,将其简化为 O(1) ,这部分可能需要双指针的做法,可以参考其他博客。