刷题算法必读|面试向的刷题小技巧
前言
掌握此技能的好处在于:
当你设计出了某一时间复杂度的算法,可以根据数据范围大致判断其是否可以通过。
不会问「为什么我的代码超时了」这种问题。
例如你设计了一个时间复杂度为O(N3)的算法,而这道题 N 的最大值是 1000,你的代码超时了,你应该就知道是时间复杂度太高了,应该进行复杂度层面上的优化,而不是去这改一改变量,那改一改范围。如果经验足够丰富,应该在编写代码之前就能大致清楚代码会无法通过。
调试代码的能力
掌握此技能的好处在于:
难道你想用人脑模拟运行吗。
不会问「为什么我的代码没有通过xx 测试数据」这种问题。
首先不推荐如何速成刷题(例如背题、套模板等),所以这不在讨论的范围内。
一般来说,刷题需要至少持续三个月的时间。面试中遇到的算法题大多都是 easy-medium 难度(那为什么很多面经都是 hard 难度?「不幸」者偏差罢了。只有遇到奇葩面试官或者乱七八糟的题目才会去网上吐槽),看到题目就会有一些初步的想法,然后根据自己到思考(或者面试官的提示)进行优化,得到答案并实现代码。一般不会遇到想半小时还想不出来的题目,所以刷题更重要的是「熟练度」。
基于此,推荐最好的刷题方式是如下的两步法:
第一步:根据专题分类进行刷题。这一步可以看成「学习一个知识点 A」「在力扣上找到若干 道知识点 A 相关的题目」「刷掉它们」。
举个例子,比如今天我想学习滑动窗口,就可以首先找一找滑动窗口相关的资料进行阅读,理解后在力扣的题目标签里找到「滑动窗口」挑选几道题目(如果你是尊贵的力扣会员的话,直接按照出现频率排个序就啊好哦了)。在挑选题目的难度上,我建议按照 easy-medium-hard 的基本顺序,因为你是在学习一个新的知识点,所以首先肯定是要看看最简单的题目是什么样的,当然在最后你也要通过 hard 题看看难度的上限,例如是否需要结合其它知识点,是否需要进行一些转化之类的。
第一步的作用在于「熟悉所有面试相关的知识点」。很多同学在知识储备不充足的情况下,一上来就随机刷题,效果是很差的。
第二步:根据你喜欢的方式随机刷题,例如按照公司 tag,跟着每日一题,或者随机抽题。为什么要「随机」刷题呢?这是因为在实际的面试中,你(在不思考的情况下)并不能知道面试官给你的题到底使用什么方法解决。在第一步中,我们要学习滑动窗口,刷滑动窗口的题目的时候你是知道「这题需要使用滑动窗口」的,而在面试中你并不可能知道。
如果你是卷王,我推荐你把题库刷穿。
否则,我觉得 300-500 题就是一个很不错的刷题量了,虽然题库已经有超 2000+ 的题目,但 300-500 的量适合大多数来力扣的同学,如果有兴趣想要深度探索,那么学无止境,更多的题解等着你来通关,你一定会感受到那种上头的感觉。
需要做力扣的周赛和双周赛吗?
周赛和双周赛相当于上面我说的第二步,即随机刷题。
如果你还没有完成第一步,建议不要尝试。
如果你正在进行第二步,那么这些比赛是一个很好的检验自己能力的机会。
当然不得不说的是,比赛的难度(尤其是第 4 题)是高于面试的,并且时不时会有一些面试不会考的知识点,所以如果发现自己做了 600/800/1000 题的时候比赛还没有办法做出第 4 题的话,也不要慌。
时间复杂度和运行时间并不是一个概念。面试时我们一般追求的是优秀的时间复杂度(即O(N)优于O(N2)),而运行时间除了与时间复杂度有关以外,还和时间复杂度中的常数有关。
例如方法一对数组 a 进行了 4 次遍历,而方法二对数组 a 进行了 1 次遍历,虽然它们的时间复杂度都是 O(N),但方法二的常数较小,因此更有可能得到短的运行时间。
而实际的代码编写中可能需要考虑的不止这些,例如测试数据以及操作系统本身就是不可忽略的因素。例如对于一个长度固定 10000,元素均为正整数且小于等于 10000 的数组,测试数据是可能为 1000010000 这一天文数字,而实际的测试数据只有几十、几百组,在力扣上运行较快的代码可能是「过拟合」的。由于 cache/memory/cpu 这些硬件都是进程共用的,力扣的评测系统运行你的代码时,它们的状态也不是固定的,所以同一份代码运行多次的时间也会不相同。
此外,打败的百分比还和提交的时间以及测试数据的更新有关。每周更新的竞赛题提交的人数少,很容易打败 100%。题号排在前面的题会时不时更新测试数据,而力扣给出的是运行所有测试数据的总时间,所以往往会比早提交的人用的时间多。
小技巧
对于刷一道题目而言,如果时间充裕,正确的做法应该是:
一定要首先给自己一些时间思考。
如果直接做出本题,应该去看一看题解中有没有更优秀的做法。
如果没有做出本题,应该去看一看题解的思路,复盘一下自己想出了哪些部分,没有想出哪些部分以及原因,通过这样的总结不断提升自己。
如果不思考就看题解,那么就没有留给自己思考的机会。题解里是不会出现展现自己的思考过程的(尤其是错误的思考过程),就算有,想通过读一遍思考过程就能达到相同的思考效果也是不现实的。
其中有部分同学,感觉会把重点完全放在 AC 一道题目中,其实对于个人技能成长来说掌握和挖掘题目深层次的东西,比 AC 题目的快感更重要。
面试中考察的是对相应产品的理解,主要是看你的熟练度,如果要想代码写的好,刷题是王道,经典的库都是最优写法,这些需要持续不断的阅读积累才有机会脱引而出。
BY /
本文作者:zerotrac
编辑&版式:Janson
声明:本文归“力扣”版权所有,如需转载请联系。
点个在看,少个 bug
微信扫码关注该文公众号作者