登录
  • #刷题
  • #工作信息
  • #求职
  • #攻略

胖头龙的咸鱼刷题笔记-算法篇

胖头龙
13000
89
天下刷题方法千千万万,每个人的资质、特点、喜好都不同,所以大可选择适合自己的方法,不必刻意拘泥于某一种形式,只要对你有效果,就是好方法。

神有神的天赋,霸有霸的套路,对于学弱和咸鱼,也可以有帮助自己成长翻身的方法。

本篇仅是一名转专业学弱总结的算法题刷题方法,也许看起来不那么聪明,但对于没有基础的小白来说,可能也是一种启发和参考。当然如果你是大佬,那自然可以略过。

第一章 一些“方法论”

在展开具体的干货前,先唠叨一些看起来没用的“废话”。

“废话”1:几条需要着重强调的学习要点

系统性的分类学习

先学会看懂答案

注意代码风格的养成

反复训练

详细的笔记

提升讲题能力

任务分配管理

系统性的分类学习:

对于计算机基础不扎实的同学,如果按照高频顺序刷三百题,通过每道题反向获取知识,这样的方法不是不可以,但效率可能不高,还会造成知识零散化,不能融会贯通。另外,松散地做300道题,对于我等学弱而言,从执行的层面而言也略显艰难。

面试算法体主要就十几类题型,套路性比较强,经过前人的总结,已经形成了比较完善的体系(300~400题左右)。即便出现很多新题(1600+),大多也能用现有知识体系去化解。

所以不如站在前人的肩膀上,通过中国学生更熟悉的“分类知识学习+核心题目+反复训练+进阶题目+复习升华+融会贯通”的系统性方法进行学习,不但基础更为牢固,而且遇到新题也有现场化解的可能。

在后面的章节里,胖头龙可以分享自己总结的,面试中常见的算法类别,大致介绍每一类需要自学掌握的要点,并附加上题目列表。

(当然大部分培训机构都有,我只是作为小白分享一点自己的心得。)

学会看懂答案:

作为一条咸鱼,在刷透300题之前,不要试图靠自己平庸的大脑跟任何题目死磕。毕竟很多算法问题的最优解,放在几十或上百年前也都是人类知识边缘的数学问题,当年大师们也花了不少功夫才研究出来发论文的,如果被我等弱鸡几十分钟就凭空搞定,大师们不要面子的吗?

所以,对于初学者,一道题十分钟没有想法就不要开脑洞了,而应该直接去寻找标准答案,以最快的速度爬到前人的肩膀上。

首先可以看LeetCode的标准答案,大部分解释的很清楚。你可以先看懂最优解,然后用自己的代码风格写一遍(答案上的代码风格参差不齐,不要被带偏),并记入笔记。如果觉得还是不清楚,那么可以直接在Google上搜题目,CSDN,博客里会出来各种大神的中文附图讲解,更方便理解。但如果一道题,你研究了一个小时还没完全领悟答案的思路(对于新手这很正常,不慌),可以先把这题暂时标注在你的记录上,过几天再回来看,不用浪费时间死磕。

注意,看答案的目的不是为了让这题混个pass,而是要理解答案中的思路,并逐渐积累形成自己的思维体系。就好比课本里的例题答案,是帮助你更好地去理解基本理论知识的运用方法,课后习题的答案,是为了方便你在做题中自我校正提升。如果你看答案只是稀里糊涂抄上去混个pass,那就没什么意义了。虽然我们是咸鱼,但并不一定要做渣,而是要做一条对自己负责任的咸鱼。

所以,不要为抄答案而羞愧,有成长的抄答案,是一种高效学习的方式。

注意代码风格的养成:

这是很多新手会忽视,也不容易掌握的点。

大多数时候我们仅仅满足于LC测试通过。但是在面试中,代码风格会直接暴露出你的实际项目经验。虽然面试更关注的是算法本身,但是如果你能写的一手正确而又整洁的代码,那绝对是加分项。我听过周围很多朋友抱怨新人同事写的便便一般的代码,可见做一个代码不整洁的人,会多么令人一言难尽。

但大部分人的整洁代码,是被大公司里严格的CR训练出来的。对于初学者怎么办呢?

首先,我们在学习变成语言的时候,就可以同时读一读这一语言的官方代码规范,虽然不可能每条都记住,但看几遍多多少少有印象,自己写到相关内容的时候,自然会想起来一些。

其次,很多IDE都自带Lint功能,平时字节写project的时候,按照lint要求把warning都修了,基本也就差不多了。自己总结的标准答案,也可以复制粘贴进去看看有没有什么问题。

最后,参考网上答案的时候要小心,很多人的答案看起来很短很酷,但是在现实中却是很糟的代码风格,或者是隐形增加了时空复杂度,所以需要有选择的汲取。一旦形成自己的代码模板,就坚持下去。

反复训练:

很多同学会说几百题刷了一两遍,但似乎依旧没有什么印象。

但是,作为一条咸鱼,你刷了一两遍就把那么多题吃透了,这个,题它不要面子的吗?它们也是花了七八年才增长到上千道的,被你两刷就搞定了颜面何在?

想想当年复习托福,GRE,那些单词你背两遍就都记住了吗?况且算法题比单词复杂多了吧。

我们不是神,并且同学们大多都是二十多岁的中老年人,不应该太苛求自己的记忆力,刷一两遍题肯定是要忘的,这一点不要惊慌。

我等学弱虽然脑子慢一些,记忆力差一些,但是多来几轮还是能补上的。而且这里的反复训练中的很多轮是在回顾思路,不是反复重写,所以一道题几分钟就能过一遍,并不是那么费时间。

总之,如果一道题你刷了两三遍以下还没记住,那说明你是正常人,不要灰心,不要怀疑,再来几遍就好。

详细的笔记:

很多同学每道题写完就算了,不总结也不记录。

刚才说到需要反复训练,但刷一遍题也挺费脑细胞和卡路里的,难道不应该留下点什么吗?你的大脑也许确实带不走一丝云彩,但可以试图留下点来过的痕迹。

特别是找到并形成一道题的标准答案后,在笔记上写下主要思路和要点,对于日后复习有神奇的作用。

另外,一个好的笔记体系,能够帮你构建一个完整的知识体系,养成这个习惯,会有意想不到的效果。

其次,很多人同学觉得刷题像考托福GRE申请学校一样,只是一次性的投入。但实际上,目前互联网程序员平均在一家公司的在职时间还不到3年(包括你自己跳槽以及公司逼你跳槽),这意味着在你职业生涯的前十年,大概需要找三四次工作。在北美的就业体系内,很多人最终也不会走向管理岗位(一言难尽。。。),所以即便你有五到十年工作经验,只要你面试的岗位还是一个Individual Contributor,在面试当中很大可能还是逃不过算法题。

不过面试算法题的大致类型和范围相对比较固定,比如之前七八年虽然LC题目从100增长到1600+,但是主要知识点还是那么多,只是题目变难了,要求变高了。因此你现在总结的笔记,在接下来十年内,都是有用的,而且会被用很多次。

所以一份详细的笔记,不仅对你这次找工作有益,对你未来很多年都有用。

提升讲题能力:

很多同学面试题在LC上刷得很熟练很顺利,但是在面试白板/文档上却写不完讲不利索。

不幸的是,面试中的表达是一个很重要的环节,直接影响面试官对你的判断。特别是疫情以后基本都是线上面试,比现场面试更难用手比划,所以相比于仅仅刷题,一定要着重提高对自己讲题能力的训练。虽然你不可能总是找别人帮你mock interview,但在自己平时在做题之后,对着小黄鸭自言自语,复述解题思路是非常重要的。

除了说,学会在共享文档里画图举例子,走case,对于把问题讲清楚有着极其美妙的效果。

能不能把题讲明白和能不能把题做出来同等重要。

任务分配管理:

作为一个学弱,看到两三百道题的任务量,大约是颤抖并退缩的。特别是体会过那种刷过一两遍,脑海中却依然没有半点痕迹的感觉的人。

但是我们可以把这些学习任务,细化出来,制定成相对具体的学习计划,分配到每周甚至每天。

每完成一个任务点之后,都应该及时进行标注并可以对自己进行小小的鼓励和奖励。

这也是自我管理的技能,很多人在职场上工作过一些年可能都没有意识到,虽然总觉得老板安排的任务似乎都完成了,但其实在老板眼中你可能是个做事没有条理没有计划让领导不完全放心的员工。

其实如果你养成了合理安排工作计划,并按计划执行方案的习惯,这在实际工作中将是一个加分项。不管是老板还是同事,都希望自己的组员是个有条理的人。因为在公司里,良好的执行力是实现各种炫酷idea的必要条件,而合理的任务计划和进度管理又是团队执行力的基础。

另外,能够管理好自己也是未来能够管理好别人的重要前提。

在后面的章节里,作者会分享一些自己具体的刷题计划日志,供参考。

“废话”2:基本的学习过程(是否需要培训课程)?

在全民转行敲代码风行了这么多年的今天,网上各类求职辅导课程自然是。。。和南湾的乌鸦一样多。

对于有一定学习能力的人来说,根据网上免费的信息,自己刷题是完全没有问题的。

当然对于零基础的人,选一些合适的课程,站在前任的肩膀上,会节省很多时间,避免一些坑(当然前提是你选的课程它自己不是个坑)。

所以这个问题没有最优答案,需要根据自己的情况权衡选择。

胖头龙因为转专业,不小心上过不少主流、非主流的课程(因为自己太弱,给机构送钱送到钱包哭了),掉过坑也有过收获,所以多多少少有一些自己的心得体会。

当然我也不会对具体机构和课程给出评价,免生是非。

不过从方法论出发,站在求学者的角度,探讨一下什么是一门好课,还是可以的。

对于我个人而言,选择短期培训课程,是希望对于某些需要训练才能提升的问题(算法、系统设计、面向对象设计、基础知识、技术面试套路、行为类问题、项目实战等),能获取整套系统性解决方案,并且这个方案是能够让我在课下时间重复练习以达到持续提升的目的。

针对某一类具体问题,一个“好”的,系统性的解决方案应该包括以下几个要点:

【要点-1】: 准备适当的学习材料(武功秘籍)

【要点-2】: 给出原理性解决问题的方法论 (内功心法)

【要点-3】: 给出针对各个具体问题的系统性解决方案/模板 (剑法招式)

【要点-4】: 系统性地指出难点和要点,以及需要避免的易错点和误区 (命门要害)

【要点-5】: 通过具体实例展示如何通过套路解决问题,启发思路,训练思维方式 (演示指导)

【要点-6】: 能够独立反复训练并验证,逐渐提升自己对套路的掌握,对内在原理的领悟,得到相应技能的持续进步(勤学苦练)

其中【要点1~5】是我们希望从课程中获得的,【要点-6】除了要求课程的具有可重复训练,主要靠自己努力。

其实仔细想想,会发现这些要点不仅仅是我们对课程的诉求,也可以是我们自学刷题的整体思路。因此即便我们完全自己学习,也可以按照这些内容进行准备。

以解决算法题面试这个目标为例,稍微展开一下这些要点:

(1) 准备适当的学习材料(武功秘籍)

如何从海量的信息中提取恰到好处的内容,也是一门技术。

有些课程大而全,会提供很多详细的内容,当然从学习的角度而言,学了并没有坏处。只是面试基本考不到,如果你时间紧,那么就是浪费时间。

有些机构比较懒,连基本材料都懒得给你准备,丢给你一个网站,或者让你自己google。当然他们会说这是培养你自主学习的能力,但是你买不买账,全看自己判断。

不过好在对于算法题而言,目前的学习资源还是比较明确的。

<1> 所选刷题语言的入门材料(大部分人都是 Java 或 Python),不管选哪个语言,常用数据结构的增删查改操作要熟练,基本逻辑、类,要会写,代码风格、规范要掌握。

<2> 十几种常见算法的基本原理和思路。

<3> 题库,一般是 Leetcode 为主,可以偶尔辅助 LintCode。题目范围主要是总表前两三百道高频,按公司分类的高频,和网上的各种面经。

<4> 解题答案,课程应该提供标准答案,自学的话自己总结。

<5> 面试技巧方面的内容和经验。这个对新人来说并不容易获取,多看看帖子,找过来人mock一下效果会比较好。

(2) 给出原理性解决问题的方法论 (内功心法)

解决算法题的核心思维方式,破解问题的思考步骤,优化取舍的基本判断依据。

一般来说自己领悟到这些需要大量时间的训练,另外大部分机构的课程在这方面做得也一般。他们更多地是讲解每题的具体解法(毕竟这样比较容易),能做到醍醐灌顶,融会贯通的,毕竟只是少数。

(3)给出针对各个具体问题的系统性解决方案/模板 (剑法招式)

针对题型分类准备相应的模板和一般思维流程,对一些更具体的子问题做一些准备和探讨。

这一点,通过自己钻研也是可以总结出不错的模板的,当然大部分课程也都能做到。

(4)系统性地指出难点和要点,以及需要避免的易错点和误区 (命门要害)

一些题目的易错点和需要小心处理的点,面试中容易犯错的误区,以及与面试官的沟通要点。

除了熟练做题之外,清楚地讲题也是重点。

(5)通过具体实例展示如何通过套路解决问题,启发思路,训练思维方式 (演示指导)

老师演示指导面对一道题,如何提问明确面试官需求,如何破题,该往哪个方向思考,然后如何套用模板把问题解决。

教会一个人思考是很难的,所以很多课程更多的局限于知识的传授,而不是启发思考。

另外少部分课程“觉得”他们做到了启发思考,但其实仅限于老师不断的说“我在教你思考”,却没有实际效果。

所以市面上真正能做到“启发思考,传授思维方式”的好课,目前屈指可数。

(6)能够独立反复训练并验证,逐渐提升自己对套路的掌握,对内在原理的领悟,得到相应技能的持续进步(勤学苦练)

这个比较直观,以上面总结出的方法,练吧。

当然具体训练的时候,也需要分主次,分轻重。

这里刷几百题是有质量区别的,不是说均匀的每题过一两遍,而是按照优先级高低分主次。

题目优先级分类

一般来说,在我的个人笔记里,把题目分为四个优先级:

<1> 必背,大约20~30道,都是各类型题目的典型模板题,基本需要刷十几遍,做到迷迷糊糊半昏迷状态也能熟练默写的肌肉记忆状态。

<2> 核心,大约100~150道,主要是各种高频题和经典题,基本在5~8遍以上,需要做到最优解,medium难度10分钟以内,hard难度15分钟以内,无错一遍过,同时要能解释清楚思路。另外有多重解法的也要掌握,知道不同解法间的优缺点和trade off原因。

<3> 重点,大约200~300道,核心题之外的高频题,基本在5遍左右。这样遇到原题或者类似题的时候,基本思路、逻辑不会错。能不能临场完全bug free要看基本功和运气。

<4> 普通,上述题之外所有你刷过的题。基本上做过一两遍,有个思路,临场遇见了不会慌。

总体而言,在分类学习入门之后,300~400的题量(也就是优先级重点及以上)差不多是可以找工作的(当然有大佬告诉你100道也能找到那也是真的,不过那可是大佬)。

刷题力度分类

如何在短时间内刷/过这么多遍也是有技巧的,并不是每次都要手写一遍,并不是每道题都要死缠烂打不会做不罢休,适当的迂回转进,提高整体效率才是目的。

下面是个人对这些基本操作(刷题力度)的定义,比如刚开始刷题的时候初刷、精刷比较多,中期过题、复刷比较多,最后阶段过题和模拟比较多。

具体的分配示例,在后面计划日程的章节有所分享。

初刷:

新手期遇到新题,如果短时间内(五分钟)没有思路没关系,不要死缠烂打,早点看答案。

找到最优的答案并尽力去理解,用自己的面试语言和规范的代码风格进行“抄写”,不完全懂也没关系,标注一下,以后再看。

每题时长控制在半小时之内。

精刷:

针对初刷过还未充分理解的题。

尽量全面理解答案的要义,并且至少在能自己“默写”出来,并调试通过。

将解题思路和形成的标准答案加入到笔记当中。

如果实在不能完全领悟,需要在笔记中用显著符号标注该题,写下困惑的地方,过一段时间再试试看。

每题时长控制在一小时之内。

过题:

按照笔记的标签(比如按分类,或者按优先级)大量复习题目。

针对做过的题进行复习,如果对这一题还有映象,则在大脑中过一遍解题思路及实现中的细节要点。

如不记得,则进行主动思考寻求解法,之后对比之前的答案和笔记,看是否正确。

如果不正确则需要强化思考并记忆,不需要写题。

每题时长控制在5-10分钟内。

复刷:

针对做过的题进行复习。好

自言自语clarify题意,讲请楚自己的思路,写题,检查,跑case,争取bug free一遍过。

只有参考笔记和标准答案复盘自己的错误和不足。

每题时长控制在20分钟内。

模拟:

抽取一道新题,看能不能做到复刷中的效果目标。

把题目记入笔记。

每题时长控制在30分钟内。

回到话题本身,如果你决定准选择一门课,但你在上完课前,并不知道这门课/机构靠不靠谱,怎么尽量避免掉坑呢?

(1)研究一下课程表,至少知道大概要说什么内容,然后看这些内容是否满足我们说的这些要点,另外从课程内容和价格也可以了解性价比,不同课程间可以比一比。

(2)上试听课,和主讲老师聊一聊(和老师聊,不是客服,客服只负责营销和教务),感觉一下靠不靠谱。不过大部分机构的试听课都一半的篇幅是营销,另外一半大概能透露一些这个老师的讲课风格,所以可以稍微感受一下。

(3)最可靠的方式是找到你周围上过这些课的同学、朋友,聊一下看看他们有没有通过这些课找到工作,或者细聊一下课程内容和上课方式,看能不能达到你的要求。

(4)网上、论坛上明显有差评和争议的课程需要谨慎。另外,满屏彩虹屁的营销文章基本不用看,很多文章作者都是国内写手,连班加罗尔在美国还是印度都弄不清。

(5)不过核心目的还是学习知识,真上当了除了尽快解决纠纷,还需要尽量调整心态,专注于找工作。

最重要的,不管报不报班,还是得靠自身努力,题还是得自己刷;可以花钱买来武功秘籍提升效率,但是最终的汗水和收获,都属于你自己。

“废话”3:需要刷到什么程度?

在讨论详细的学习计划前,先定义一下学习目标是什么,或者说期望的学习效果。

对于算法题,作者拍了一下肚子,装X地分成了四层境界(仅代表个人意见及恶趣味):

第一层境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 (手中有题)

(一只学弱从坐标0点出发,100小时左右可以达到的状态)

总题量 <100 。

能认出旧题,识别出考点并且记得大致的思路,

在不限时间,不限提交次数的情况下,一般也能勉强完成代码。

对新题基本上无能为力。

第二层境界:谁家玉笛暗飞声,散入春风满洛城。(心中有题)

(200 ~ 300小时)

总题量 200+。

对算法模板、数据结构形成初步的认识,偶尔也能产生醍醐灌顶、幡然感悟的快乐。

对于旧题有较深的映象,有完整的解题思路,能在不看答案的情况下实现代码,基本上能在两三次提交内通过。

对于新题,大约能判断出题目的类型和解题的方向,但是缺乏对细节的实现能力,有时写的出,有时写不出。

第三层境界:衣带渐宽终不悔,为伊消得人憔悴。(人题合一 )

(500 ~ 1000小时)



总题量 400~500。

熟练掌握十几种类型,300~400的核心/重点题,对每一类题的套路了然于心。

看到原题或类似的题基本能在规定时间内完成高质量,最优的代码。可能有一些小问题(typo,API记错),导致不能一遍过,但没有思路和逻辑上的问题,基本上不会提交两次以上。

能够清晰讲解解题思路,并让别人听懂。

对于没做过的题目,能迅速地进行分类;或者对于有多重解法的题目,能分析不同类解法的要点和优劣,理解取舍的原因。

基本上能根据自己想出的思路正确地实现最优解的代码,但可能会有一些细节考虑地不周到,造成提交超过两次。

在讲解这些没做过的题目的时候,可能不太流畅,但最终也能说得通。

第四层境界:两岸“猿”声啼不住,轻舟已过万重山。(天下无题)

(几千小时?我也不知道要久能到这个境界,显然我自己没练到。。。不过不影响,乾坤大挪移的作者也没修炼满,照样编第七层)

实现了对面试中所有常见类别的算法题套路与解法轻车熟路,完成了理论体系的融会贯通。

深刻理解题目的内涵,清楚的理解当一些题目条件发生变化时将对题目的解法与复杂度产生什么样的影响,能够大致猜到follow up的方向。

不管题目有没有做过,看到以后都很快形成清晰的思路,找到面试环境下的最优解,同时对一些需要注意的常见代码细节了然于胸。

能清晰流畅地表达讲解自己的思路。

在较短时间内流畅且无错地完成符合规范的代码,一气呵成。

整体而言,为了能较好的通过大部分面试,一般需要修炼到第三层境界。

当然如果经过努力最终到达第四层境界,至少在算法这个分项上,你大概已经咸鱼翻身成为大佬,具备手握包括顶级大厂在内的N个offer,在HR之间比价聊包的资本了。

如果你说你刷了一遍题就到达第四层境界,很好,大神你很优秀,目送您出门好走。

当然具体的时间和题量都因人而异,毕竟面试这件事并不是一个标准化事件,很难一概而论。

所以,我只是分享自己一只学弱的经历。



------------------------------- 第一章 的分割线 ----------------------------------------

好的,终于差不多聊完了第一章的三段“废话”。

接下来的章节计划先分享一些笔记体系和刷题日程安排,然后再按算法分类进行一些分享。

(未完待续)

补充内容 (2020-10-26 06:41):

更新番外篇: 转行刷题,是否一定要报班?有疑问的小伙伴可以看作者的另一个帖子,防坑指南:



补充内容 (2020-10-26 06:44):

更新至第二章:刷题笔记体系,作者用回复功能续更在这个主题里。为了方便大家使用“只看作者”功能,我可能就不单独回复大家的提问了,请见谅~

补充内容 (2020-11-7 11:35):

更新至第三章:刷题方法

补充内容 (2020-11-16 08:00):

更新至第四章:程序基础

补充内容 (2020-11-16 08:23):

更新至第五章:二分法

补充内容 (2020-12-6 07:28):

更新至第六章:多指针 (更新的时候,系统显示需要审核~可能需要一两天)

补充内容 (2020-12-31 09:44):

更新至第七章:宽度优先搜索 (最近比较忙,更新略慢,请见谅)
89条回复
热度排序

发表回复