当青训营遇上码上掘金-主题四攒青豆

61 阅读1分钟

当青训营遇上码上掘金

问题描述

主题 4:攒青豆

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

4795ddeab286477880b5dcd6422d1404_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

解决思路

  • 首先使用的是典型的 双指针算法
  • 一个柱子上面的青豆数量与他的左右最高柱子的最低高度有关,于是我们可以设置两个指针 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
    • 当前情况肯定是左侧最高柱子高度小于右侧最高柱子高度,如果右侧存在比该柱子低的,则因为有左侧和右侧“包着”该柱子,故无须考虑更低柱子的问题;如果有比该柱子更高的,则自然而然,上述式子成立

归纳