主题四:攒青豆|「青训营 X 码上掘金」主题创作活动入营版

99 阅读3分钟

当青训营遇上码上掘金

image.png

前言

在机缘巧合之下,我从网络上了解到了此次字节跳动和掘金一起举办的青训营活动,便拉着同学一起组队参加了。十分开心能够顺利通过入营考试参加到此次的课程之中,希望在接下来的学习中能够获得更加丰富的知识和相关的编程经验。

选择主题

由于我选择的后端学习,因此从给出的四个相关创作主题中选择了攒青豆这个题目。题目的具体要求如下:

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

以下为上图例子的解析: 输入:height = [5,0,2,1,4,0,1,0,3] 输出:17 解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

题目分析

从给出的题目和例子中可以看出,此处的设定应该是一个横竖1*1的单位格子内放置一个青豆,我们需要获得这些柱子组合中能够放置的青豆总数量。首先由木桶最短版的原理可以联想到-两个柱子之间能够放多高的青豆是由二者之间较短的一根柱子来决定的,因此这应该是一个找短版的题目。可以设置两个指针分别从左右两边向中间走,得到每一个横坐标上可以放置的青豆数量并进行累加就可以得到最终所有的青豆数量。

代码思路

首先设置两个边缘柱子:左柱子‘l_pillar'和右柱子'r_pillar'分别是给的数组的第一个值和最后一个值。再然后设置左右两个活动指针'l'和'r'分别指向第二根柱子和倒数第二根柱子。比较‘l_pillar'和’r_pillar‘指向的柱子高度,较矮的一方柱子靠向中心的一个横坐标中柱子加青豆的高度最少都能达到矮柱子那么高。我们将矮柱子的高度减去它靠近中心那格的高度就得到了它靠近中心那一格攒到的青豆数。当然,矮柱子靠近中心的那一格有可能比矮柱子高,此时得到的青豆数量就是负的,因此青豆数量大于0的话就累加到总的青豆数量之中,青豆数量小于0的话就舍弃。处理好此轮青豆之后就考虑柱子和指针的移动,将矮柱子高度与当前累计青豆的格子高度相比较,如果当前累计青豆处的格子高于矮柱子的话,就更新矮柱子高度,否则不更新。最后将这一边的指针向中间方向移动一格并结束此轮。直到两个指针相重合结束青豆的累加。代码如下:

总结

最终问题得到解决,双指针的应用在很多实际问题中都是很好的解决方法。希望大家可以指正交流。