「青训营 X 码上掘金」—— 攒青豆
当青训营遇上码上掘金
主题介绍
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
解题思路
首先,为了计算每个柱子能够接住的青豆数量,我们需要找到每个柱子左边和右边第一个比它矮的柱子。然后,我们就可以用左右两侧较低的柱子高度减去当前柱子高度,再乘以两柱子之间的距离,得到该柱子能够接住的青豆数量。
方法一:暴力求解
遍历每个柱子,找到两侧柱子高度较低的那一个,计算两柱子高度的差值即为该柱子能够接住的青豆数量。但是,这样的复杂度为 O(n^2),在 n 很大的情况下不够优秀。
方法二:双指针法
双指针法的时间复杂度为 O(n)。我们从数组的两端向中间移动两个指针,并利用双指针的方式,维护两边的最大高度,如果左指针指向的柱子高度比右指针低,则将左指针右移;如果右指针指向的柱子高度比左指针低,则将右指针左移。如果当前柱子高度小于两端的最大高度,则该柱子可以接住青豆。最后将所有接住的青豆数量加起来即可.
代码实现
本文提供的Java实现双指针法代码如下: