卷王 ,不能倒在刷力扣的路上
前言
大家好,我是bigsai,好久不见!
最近在一些群聊、私聊中遇到很多小伙伴的一个问题就是:刷题,大家也都重视到算法刷题对冲击大厂的重要性,越来越多的人开始卷起来了!
但有的小伙伴是这样卷起来的,倒在刷力扣的路上,卷的自己都懵了。
今天,我就给偏初学者的各种问题谈谈个人刷力扣这方面的观点。
刷哪些题?
大家刷力扣,目标肯定让自己有能力面对大厂的面试笔试,小部分就是为了坚持刷题保持感觉提升自己算法编程能力,那么你肯定要把重点内容先掌握,哪些是重点内容呢(今天只讲题的重点)?
剑指offer:
剑指offer:https://leetcode-cn.com/problem-list/xb9nqhhg/
剑指offer的优先级还是很高的,就业必刷。在牛客上和力扣平台上都可以刷剑指offer的题,但是更推荐力扣这个平台,我第一次刷剑指offer就是和大家在牛客平台上刷的,部分题(很少)牛客ac的代码提交到力扣试了一下发现wa了(也找到问题)。所以牛客测试数据相对还是比较弱的,力扣上的测试数据相对较多,在大部分情况,你过了代码基本上就没有什么逻辑漏洞了。
剑指offer名气大,是因为剑指offer的题目是真的经典!短短66道题,内容覆盖常见数据结构比如链表、二叉树、图、队列、栈、哈希表等等,常见的算法和经典问题包过二分、动态规划、全排列问题、滑动窗口、贪心、分治、排序、位运算、dfs、bfs等等,刷完这些题,是真的可以收获和学到很多!
另外推荐刷剑指offer的原因是因为剑指offer在面试笔试中出现是真的非常高频 ,面试官考察的题目一般都是经典题,面试官不创造题目,只从题库中抽选题目,而抽选题目的来源基本就是力扣和剑指offer,剑指offer是非常高频的题库之一。
力扣HOT100|力扣前200
力扣HOT100:https://leetcode-cn.com/problem-list/2cktkvj/
力扣前200:https://leetcode-cn.com/problemset/all/
优先推荐力扣HOT100,力扣HOT100是对力扣某一时间(因为力扣题一直在增加)题库选出的100道优质题,这些题跟剑指offer类似,都是一些高频问题,有些题和剑指offer重叠,也有不少问题确实还是有难度的,对很多人来说特别容易卡壳,难题可以放一放后面再做。但是如果力扣HOT100能刷完,那你其实加上剑指offer快200的题量就挺可观的了。
力扣目前已经有两三千道题目,并且还在增加,所以想刷完力扣,几乎是不太可能的,如果想顺序刷,还是推荐前200,力扣前200和力扣HOT100重合很大,前两百质量还是很高的(不是说后面质量不高,只是那么大题库刷到后面就会出现很多同类型、同套路的题目),所以还是推荐刷完力扣前200的。
刷完这几个部分大概能够拥有接近300高质量题的刷题量,我觉得应对大部分的互联网公司面试是足够足够了,出一些变换自己也能够相对容易的看出来。
刷题顺序?
上面列举了待刷的题库,既然知道了要刷哪些题,有没有一个比较推荐的刷题顺序呢?是否需要分类刷?
是否要分专题分类我感觉这个看人的。
如果你有数据结构与算法基础,比如考研或者平时数据结构学的还不错,常见数据结构与算法原理明白能够实现部分,又或者有部分刷题经验,那么我推荐你直接顺序着刷就完了。从客观来说,力扣和剑指offer上面的题目有难题,也有需要高级数据结构的,但更多的是在数据结构或者逻辑基础上的巧妙思维题型更多,如果你有数据结构与算法的基础,你还是比较容易get到考察点的。顺序刷的途中遇到某个不会的技巧或者数据结构,学习一下加入自己的"脑库"中即可。
如果你是真的小白,那你就要为自己手动找到一条可行走的路,那我推荐你可以按照一些专题去各个击破。因为你是小白如果顺序刷这个题不会,学了,再刷下一题,又学了个完全陌生的新东西,短期内学习太多比较陌生的新东西很难吸收,很容易忘,就会陷入怎么都学不会的苦恼中。所以你可以把刷题当成一个台阶,一层一层往上爬,刚开始找easy easy 那种a+b类型的题求过,后面慢慢增加难度(很多数据结构或者算法技巧相对独立,每个人觉得难的不一样这里就不列举了)。对于数据结构方面的题,从链表开始先学透单链表、双链表、循环链表各种插入删除实现,然后在题库中找链表相关题进行逐个攻破(链表中的也可细分链表插入、删除、反转、合并、查找、排序等等),链表大专题之后二叉树大专题、哈希…… 这样你短期内学习某一个数据结构或者算法技巧,多去刷题巩固吸收效果比较好!在这种情况切勿觉得简单就草草下一个,你不敲代码,可能不会知道自己会出现什么问题。
三个为什么
为什么见到一个题没思路?
这种情况大概率是因为见少了,刷题也是个缓慢的过程,见得多刷的多些,来的感觉才能更快一些。还有一部分可能因为给自己安排的刷题路线不够平和。你上来去肝hard难度的没思路不是很正常。
简单题很容易懂实现起来很难?
这种情况可能基础逻辑可能缺乏训练,对编程语言的集合框架掌握也有所欠缺。有些题可能涉及到集合框架(Map、Set、List、Stack、Queen)各种嵌套、联立需要你有个清晰的层次感和逻辑。
你刷题,需要熟练使用一门编程语言,熟悉这个编程语言的常见操作api、集合框架、函数,这些是解决问题的工具帮助我们提高效率(不至于每次手写个队列、手写个哈希表吧)。
这个问题推荐可以先刷几道简单的字符串处理问题,字符串处理问题很多涉及到的集合框架和逻辑控制比较多,如果时间充足推荐PAT乙级的题目刷一些练手锻炼逻辑和编程语言掌握。
看了很多题解为啥还是不会刷题?
看了很多题没刷那跟没刷区别不太大,印象微弱。从学习角度,刷题和我们学数学的方式有点相似,学会了数学题公式和例题,但还需要大量练习才能真正掌握。
只有自己亲身敲了每一行代码,每一行代码逻辑是什么,是自己思考出来的而不是看懂别人的思考。从0到1完整实现整个程序,这才能行成一个完整逻辑,然后可能出现各种bug自己调试看看找出问题。
可以看题解,看了自己要能完全写出来才行,如果刷了1000+题,你看了题解不刷没问题,看个思路过了被卡的地方就行。但如果刷了100不到,那你看懂还是老老实实按照别人的逻辑闭卷式的复现一遍。不去实现说有很多问题,记不住,也没啥奇怪的。
总结一下,如果刷题量不到100感觉状态不行就简单粗暴多刷题先,如果刷了两三百状态还是很差那么就要好好找一下其他原因。
拿到一道题的处理流程
拿到一道题,正确的刷和学习方法是怎么样的呢?
确定考察点、确定思路
读到一个题,读完题意后首先就是要了解这个题到底考察的内容是什么?当然如果你按照专题来刷,那可能这方面就容易很多。首先可以确定下题型大类型,是图论的,还是二叉树,还是字符串的?就要拿这个类型的题目往这个范畴常见算法上靠。比如给个数组数据让你查找计算,有可能是双指针,有可能是哈希,有可能还是位运算,还可能是动态规划,还可能是要贪心处理。不过大部分题是在各个经典算法的经典问题上进行一些变化,要知道经典算法处理的哪些经典问题。
如果能确定考察点,可以想想细节开始实现;如果确定不了考察点,没思路,先别直接看题解,看看题目标签的提示。有时你看一个题可能说:这题啥方法啊我只会暴搜,有的确实就是搜索剪枝……
除了标签,还要看数据范围!数据范围内的数据都是可能出现的,不同数据范围可能使用方法不同(这点数组题较多,有些题巧用哈希、原地置换对数据有要求)。
如果自己看了标签想想来灵感那最好,如果还是没有灵感,那点一下题解。可以从标签标题中看看能不能有灵感,有不少题解会给足够多的暗示有些人看到就能明白了。
如果还是不会那就老老实实点进去看看别人的思路,有的是视频,有的是图文,看懂为止,要是还自己看不懂,要么请假一下别人,要么放弃吧!
编写代码、测试
编写代码的过程不要有任何参考!编写代码的过程不要有任何参考!重要的话说两遍,思路可以看,别人的代码也可以看,你自己写代码不要参考和ctrl c + ctrl v,工程项目能跑起来就行为了效率都是cv大法,但是面试笔试题基本要你闭卷,有的还要你用在线IDE连提示都不全的。
写代码常常要考虑常见问题:测试数据边界(比如Integer.MAX_VALUE,Integer.MIN_VALUE这种边界数值),循环控制边界处理,末尾数据处理(有时候会被遗忘处理),特殊异常情况考虑,数值范围是否合理,算法复杂度是否能够跑出来,数据深浅拷贝,简化重复遍历和操作,变量命名清晰,注释较为完整……
写完代码,用测试案例多测测,确保万无一失。力扣经常出空值测试案例,因为这个wa了很多次……
如果出现和想象中不一样的问题,先看一遍自己代码逻辑看看能否看出问题,如果看得出正好,看不出的话自己打印输出或者debug找找问题,直到改对为止,有很多题需要考虑比较全才能ac。
方法、结果对比
不要以为ac了就完了,你要看看自己时间上超越了多少人,推荐从这两个维度来衡量自己的代码:
要超越70%以上的人(根据自己要求适当提高):大部分题超越70%说明你的方法上是没问题的,可能有些小的方面可以进行优化。比如StringBuilder替代String进行字符串拼接,使用char[]数组替代String进行遍历枚举等等。
自己的方法在好方法时间范围内:有些题比较卷,大家都是最快方法你的代码可能比别人差1ms就显得很慢,这时你只要确定你的方法很优秀就可以不一定要追求100%,并且这个时间花销不同评测姬出来结果可能也不同的。可以看看大家的时间花销区间,如果你的方法跟最快的在几ms或者30%时间范围,其实都是ok的。别人4ms,你5ms没啥问题,别人50ms,你70ms也没啥问题,但是如果别人80ms你800ms那差的太多就要看看自己逻辑和代码了。
另外,力扣你点击前面时间的柱状图是可以看到别人时间开销较小的代码(有的现在跑可能因为测试数据变动没那么快了),可以参考学习一下别人的处理方式。
巩固提高
过了这道题,可以看看题解区别人有没有更巧妙的处理方法,当你自己ac之后和别人有个直接对比印象会比较深刻:还可以这样!
力扣上hard题一般逻辑量大或者难,easy和mid可能简单,但有些题目后面反问你能用O(1),O(n)等等限制条件解决的还是很需要技巧性的,有必要掌握!
如果感觉这类题型掌握不扎实还想再练一下可以看相似题型去及时巩固一下。
结语
上面的一些方法仅限于给一些初学者建议,不一定很准确高效可以参考,如果上面题差不多有闲余之力,推荐可以跟着每日一题打卡,半年就是180+题量,一年就是365题量,相当客观!
文章转自公众号:bigsai