当青训营遇上码上掘金
题目
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
思路: 这题的解法有许多比如单调栈、按行求、按列求、动态规划、双指针、动态硅规划等选择哪种解法取决于个人对于这些解题方式的理解。这题对于使用动态规划的思想来说是可以的。比较难的地方是在于开始阶段如何去初始化值。 首先,需要找到左边和右边最高的豆子,由此我们可以定义两个数组变量l,r分别代表左边豆子的高度和右边豆子的高度,l[i]是左边最高的豆子,r[i]是右边最高的豆子,之后就以这两个数组进行递归。 对于下标i,青豆能到达的最大高度等于下标i两边的最大高度的最小值,下标i处能接的青豆量等于下标主处的豆子能到达的最大高度减去 height[i]。 朴素的做法是对于数组height 中的每个元素,分别向左和向右扫描并记录左边和右边的最大高度,然后计算每个下标位置能接的青豆数量。假设数组height的长度为n,该做法需要对每个下标位置使用O(n)的时间向两边扫描并得到最大高度,因此总时间复杂度是O(n2)。
最终代码实现
动态规划的时间复杂度是O(n),空间复杂度是O(n)。需要注意的是动态规划是典型的空间换时间,如果空间太大可能会爆内存。