青训营X码上掘金 第四题攒青豆

91 阅读3分钟

前言

当青训营遇上码上掘金。在本次入营活动中我选择是第四题,目的当然是多多赚取青豆能够拿到结营证书呀(弱小)。其实我跟这道题的渊源还蛮深的,「攒青豆」也就是传说中的「接雨水」,作为面试常青题目广为流传。当时大三年轻气盛啥也没准备就报名字节实习,我人生第一次也是到现在为止唯一的一次面试遇到了手撕题就是这道接雨水,当时在面试官的多般提示下还是没做出来,果不其然字节一面无。

后来还是想着早点做好找工作的准备,就入了卡哥的代码随想录,到现在快三个月,代码随想录一刷也基本结束了。在差不多两个月前,翻题目目录才发现当时面试的题目就是这道接雨水,怒做(怒看题解),当时是理解了暴力和优化后的动态规划两种做法,在今天完成单调栈的板块后,重新再去思考了这道题的单调栈做法。

因为这道题很多很多uu肯定都做过,理解肯定也比我透彻,我也没有什么新颖的思路,就简单说一下我在理解了这三种做法的一些小tips。

正文

其实对于我来说,做题首先能想到一个能顺利写出代码的思路,就简直快成功100%了。当时面试第一次遇到这个题,没有系统的算法刷题经历,只是有在课堂上那点可怜的算法课和大作业,完全是没有门道。后来再看了暴力的题解后,也仍是感叹好精妙(菜死了)。

我在想让我把这道题的解法忘记让我重新做一次,我能不能至少有暴力的思路。也许一刷后的我,可能会去模拟一下接雨水整个过程:接到雨水的格子有什么特点?雨水的量是由什么决定的?当我多去思考一下问题的产生,或许也可以灵光一现拍拍脑袋,噢当前格子的水量是由左边右边最高柱子中最矮的那个决定的,短板效应。 在想出一个O(n^2)的所谓双指针的解题思路后,面试官再提醒一下备忘录的使用,去减少重复过程的计算,动态规划的思路也出来了。

至于今天看的单调栈的这个板块,它的适用场景是当你需要找到当前元素值左边或者右边遇到的第一个更小或更大的时候。如果想按一列一列的去找,要找的是最大的那个,直接用单调栈就不太行。如果非要用单调栈的话,你能找的就是第一个比他更小或更大的数,让我们来想一下,遇到第一个比他更大的数意味着什么?意味着遇到了一个凹槽的产生,那么此时在栈顶的是凹槽的高度,而栈顶的第二个元素就是左边的最大高度。按照这样的思路其实是把一个蓄水的空间横向划分,而不是之前去找每一列的水量。

当然这道题下的是青豆嘛。