当青训营遇上码上掘金,又会碰撞出怎样的火花呢? 今天小白鸭带着你一起来看看青训营的攒青豆问题,教你如何用双指针秒杀它。
题目描述
-
攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
思路
这道题的本质就是 接雨水 问题。观察发现:每一列能装的青豆数取决于该列左右柱子最高高度的较小值。解释一下,就是在该列处,往左边取到左边柱子的最高高度,往右边取到右边柱子的最高高度,然后比较两者取其较小值就是该列所能容纳的青豆数。
方法
这道题我们用所谓的双指针方法来解决。双指针的本质是两种遍历的指向。在此题中,左指针指向最左边,右指针指向最右边,然后两者往中间靠。我们先单看左边一边,左指针慢慢往右的时候,同时记录下遍历过的柱子的最大值,然后跟右边的最大值(左右其实是一致的,右边的往左边遍历,记录下的是右边柱子的最大值)比较,如果左边的大,那么对于右边的来讲,无需再找该列左边的最大值,因为比左边的次小值(也有可能刚好是最大值)都小,那么肯定比左边最大值小,这样左边就无需继续遍历,节省了时间;否则反之。在这个过程中,我们可以用左指针作为数组遍历的指针,当然,你也可以重新定义一个新的指针来使自己的逻辑更清晰。
代码实现
点击运行即可看到结果。因为掘金并不支持输入接收,所以把输入写死在代码里,如果要验证其他的其他数组可以直接改 main 函数里的 heigh 数组。
刷题心得
- 把每一道题的思路记住。无论是不是你自己想出来的,就跟写文章一样,有一定量的输入才有输出;
- 选择一种适合自己的解题方法。有了做题思路还不够,你需要有方法来帮你提高效率,因为暴力解法并不是最优。同时,先学会一种方法,等掌握熟了再研究其他解法;
- 全盘考虑。有了思路和方法,并不一定能够将代码很好地实现。很多时候,我们写完代码一测试,就会发现自己漏掉了一些特殊情况,比如数组为空,数组只有1个数等等,这就说明在开始写代码的时候,你并没有全盘考虑,所以你写完代码测试之前,不妨再思考思考,这也能锻炼你的逻辑严谨。
- 掌握一定的语言语法才能信手拈来。很多时候,我们肚子没货,连一种语言的基本语法都不熟,那写起代码一定会非常难受。但冰冻三尺非一日之寒,慢慢在刷题的时候提升自己,这也是一种方法,一开始并不要着急,多查查相关的资料,相信你会有更深的理解。
- 时间不够,题解来凑。有可能有像笔者一样,今年暑假面临找工作的重任,准备的东西太多,时间不充裕,那么快捷的方法就是拿别人的题解来快速把题过一遍,毕竟,站在巨人的肩膀上,我们看的更高更远。我推荐labuladong刷题网站(Java为主),代码随想录刷题网站(C++为主)。
引用
最后祝大家除夕快乐,在新的一年里兔飞猛进!!!