当青训营遇上码上掘金
问题描述
主题 4:攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
解决思路
- 首先使用的是典型的 双指针算法
- 一个柱子上面的青豆数量与他的左右最高柱子的最低高度有关,于是我们可以设置两个指针 l 和 r,分别从左右来往中间移动,并且设置lMax和rMax来表示左右最大高度
- 从而我们得到两种状态
height[l]<height[r],更新lMax和rMax,则一定会有lMax<rMax,此时我们就可以用lMax-height[l]来表示当前l柱子的青豆数,并且将l++height[l]>=height[r],更新lMax和rMax,则一定会有lMax>=rMax,此时我们就可以用rMax-height[r]来表示当前r柱子的青豆数,并且将r--
疑问
注意:当前所说的情况是在height[l]<height[r]的情况下
- 为什么当
height[l]<height[r]时,一定会有lMax<rMax呢- 因为从一开始就是只会移动较矮的一根柱子,较高的会不动
- 为什么
lMax-height[l]就一定会得到该柱子的青豆数- 如果当前l柱子为左侧最高时,则上述式子为0
- 当前情况肯定是左侧最高柱子高度小于右侧最高柱子高度,如果右侧存在比该柱子低的,则因为有左侧和右侧“包着”该柱子,故无须考虑更低柱子的问题;如果有比该柱子更高的,则自然而然,上述式子成立
归纳
- 双指针问题的核心是只移动矮的一端,并且实时更新两端最高的 代码连接:code.juejin.cn/pen/7198117…