题目描述
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
问题分析
针对上述问题,我们先手动构造几份案例,然后对问题展开分析!
样例1:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
样例2:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的柱子高度,在这种情况下,可以接 6 个单位的青豆。
思路: 双指针解法:
-
如果后面的存在比当前柱子高的,那么就用那个高的柱子作为right, 把当前柱子的高度作为height,然后遍历 left -> right 挨个计算可以接的青豆。
-
当后面的柱子都比left柱子低,那么就要在 left -> length-1之间找一个最高的柱子maxHeight,然后,从left+1 -> max开始遍历,挨个计算可以接的青豆。
动态规划解法:
这并不是一道典型的动态规划题,但是动态规划的思想是可以应用的。难想的点在于初始化状态。
- 首先,我们需要找到所有左边最高的柱子和右边最高的柱子。我们可以使用两个数组leftMax和rightMax来存储,其中leftMax[i]代表第i个位置左边最高的柱子,rightMax[i]代表第i个位置右边最高的柱子。然后就可以根据这两个数组递推啦!
- 然后,我们需要找到每个位置的最大容量。对于第i个位置,它的最大容量就是min(leftMax[i], rightMax[i]) - columns[i]。
- 最后,我们可以将每个位置的最大容量相加,得到总的容量。
AC代码
代码片中的js代码,也就是trap函数,只需我们将柱子的高度给他,便可以得到具体可以攒到多少个豆子。已经封装完整。
总结
其实除了双指针法,还有一些其他的方法可以解出这个题目。 例如:
- 暴力法
- 栈模拟
- 动态规划
- 贪心算法
总的来说几种方法运行速率对比如下:
491959
暴力法运行时间:449046
491959
栈模拟法运行时间:1323
491959
双指针运行时间:93
491959
动态规划运行时间:261
491959
贪心法运行时间:92