这篇文章是我领会算法的心得,希望它能够给一些将要领会算法且准备要读大部头算法书籍的朋友一些参照,节省一些时间,也为了给经典的“*皮书黑**”祛魅,我觉得这些书籍在大部分互联网从业者心中已经不再是进步的阶梯,而是恐惧的阴影了,因为当一些领会路线中列出这些书目时,评论区多是调侃少是交流和讨论。在这之前我也这些书抱有读起来很困难的看法,但是在我参照过《算法导论》之后,我觉得它更像是一杯“鸡尾酒”:正文领会起来相对容易,能帮大家建立基础,后续的习题和实验,能帮助有需要的人进行深入领会,扩展的高级数据结构和数论等章节也能进行探索,就看大家怎么来利用了。
开始领会算法的契机是23年初参加《Hello 算法》开源项目的内容贡献,发现自己算法基础知识匮乏,索性准备系统地领会一下算法相关的知识,在这前后一共读了4本书:《Hello 算法》、《数据结构与算法之美》、《算法(第四版)》和《算法导论》(参照了前16章),领会期间在朋友的建议下实践了艾宾浩斯领会法,觉得收货良多。所以,本文会分两部分,分别介绍算法的领会指南和领会方法,希望对大家能有启发:
算法领会指南
我采用的专题阅读领会,以《算法》为主要参照书目,逐章阅读,每领会完一个章节都会再去阅读其他书籍的对应章节作为内容补充,并结合章后的习题练习(我觉得没有练习的算法领会都是空架子,因为大多时候看会了很可能还是写不出来,但是官方给出的参照答案补全,可以参照《算法(第四版)》参照答案开源项目)。但是事实上并不是这些书中所有的内容都值得参照,所以可以参照下面的领会方法:
《算法》的第二章排序介绍了时间复杂度为O(n^2)和O(logn)的排序算法,它并没有直接介绍时间复杂度为O(n)的桶排序、计数排序和基数排序,而是将它们放在了第五章的字符串排序中,我认为这部分并不好,所以在完成这一章的领会后,需要参照《Hello 算法》的第十一章或者《算法导论》的第八章,我认为参照前者更合适一些。
《算法》的第三章在介绍红黑树时,它写的是左倾红黑树(与2-3查找树同构),该数据结构是这本书的作者先前发表的一篇论文,它是经典红黑树的变体,实现相对容易。不过,在Java语言中TreeMap的实现采用的经典红黑树(与2-3-4查找树同构),我认为如果要扩展领会经典红黑树的话需要结合《算法导论》的第十三章和TreeMap的源码,除此之外,暂时没有发现参照领会经典红黑书更合适的材料。
除此之外,《算法》中没有对动态规划和贪心算法的介绍,这一部分在《算法导论》的第十五章和第十六章有讲解,不过动态规划和贪心算法类的Leetcode题目在我看来还是比较难的,需要结合大量的练习才行。
以上,对于 基础的算法领会 就比较全面了,下面我们来讨论一些问题作为补充:
《算法导论》需要读吗?
我认为《算法导论》真的是非常合适的算法领会参照书,由于之前我也带着“*皮书黑**”读起来比较困难的想法,所以只把它作为了补充阅读,没有以它的内容为准,如果现在让我重新选择,我会把它作为主要参照书而其他作为补充阅读。
《算法导论》它不局限于语言,其中的代码内容是伪代码实现,所以任何语言的领会者都是合适的。并且,它会用单独的章节来介绍算法中常用的策略,如分治法等,此外在数据结构中创建哨兵节点的技巧也在链表章节中也描述。我认为它的前十六章加上第二十二章用来领会基础的算法已经足够了。开篇我说这本书像鸡尾酒,因为 它还扩展了高级数据结构和更加深入的算法知识,如斐波那契堆、van Emde Boas 树、数论算法和NP相关的知识等,所以,它的知识更加全面,面向的读者范围更广。我认为作为普通的算法领会者,一定要把握好领会的度,因为算法本身相对更加耗费脑力和时间,钻牛角尖式的领会在工作和生活间调和起来是不容易的,并且在算法导论中确实有一些复杂的证明和推导存在,可以选择性的跳过,因为我们的领会并非研究和探索,这样降低了难度也提高了领会效率。
《Hello 算法》是怎样的一本参照书?
《Hello算法》是一本基础的算法书,它的作者是也是Leetcode上剑指Offer系列题解的作者,这本书的知识基本上覆盖了刷LeetCode所需要的知识,它在内容深度上没有做扩展,像红黑树这些,也正如它的前言所述:它是一本能够让你避免读大部头便具备基本刷题能力的书,如果大家在短时间内想补足算法知识的话,参照这本书足够了,但是深入的领会是必要且无法被替代的。
对于只想刷题的同学该怎么领会?
我觉得可以直接参照高频题目的题单 分类 先刷起来,然后根据题目,发现缺少的知识进行补足。这样相对更加高效,因为Leetcode具有技巧性和规律性,结合大量的题目练习是最好的方式,反而如果先啃完大部头再回过头刷题可能效率不够高,并且这样也不能得到预期的收益,因为这些书它并不是教你如何刷题的。
以上内容对于找到适合自己的算法领会路线我认为已经足够了,接下来是我在算法领会中实践过的领会方法:
艾宾浩斯领会法
我认为领会某项技能,不仅局限于算法的领会,最终目的在于形成对它的长期记忆,并不是仅仅保留印象,而形成长期记忆的方法也非常简单:即频繁而有效的重复刺激,像我们的母语和一些生活习惯(刷牙、打扮和系鞋带等)之所以不会忘记是因为我们每天都在反复的刺激大脑如何运用,乃至最后都形成了肌肉记忆。总之,领会结合规律的复习,并归纳总结,便可以克服遗忘,达到温故知新的结果。
艾宾浩斯遗忘曲线,即人对于知识的遗忘速度遵循 "先快后慢" 的原则。学得的知识在一天后,如不抓紧复习,很快就只剩下原来的 25%,而随着时间的推移,遗忘的速度会减慢,遗忘的数量也随之减少。
如果想有效抵抗遗忘,最好的办法就是进行规律的复习(每 5 分钟、30分钟、12小时、1天、2天、4天、7天、15天、1个月、3个月、6个月)。
艾宾浩斯遗忘曲线是大家都熟悉的概念,但是我几乎没有发现我的同学采用类似的领会方法。如果不是在朋友的推荐下,我也不会去改变自己的领会方式,在我实践过之后,收获很大,所以也分享给大家,下面是部分我用来记录领会和复习的艾宾浩斯表格:

我并没有完全照搬它的复习时间,而是采用了2小时、12小时、2天、7天、15天、1个月和3个月这样的时间间隔,其中表格中记录的是领会日期,绿色表示按时完成复习,红色表示没有按时复习。
采用这个领会方法我认为需要始终坚持 “循序渐进,按部就班” 的领会理念,不能一时图快而在短时间内领会过多知识,否则它会带来长时间的复习压力,也不能采取断断续续领会几天就休息一阵子的方式,而是真正地让领会成为一种习惯,慢慢地积累达到知识稳步增长的目的,这更像是投资的复利。
这种领会方法完全打破了我之前“从来不复习,永远看新的”的领会方式,并且不复习经常会带来“这个东西我看过,但是我忘了”的困扰,导致最后学完什么都没有剩下的局面,并且从采用这个领会方法之后,以“手写线段树”为例,真得可以信手拈来,像“肌肉记忆”一样,所以规律的领会和复习是很有必要的。需要注意的是:这种领会方式需要耐心、毅力和自制力的辅助,并根据自身记忆情况进行合理的调整,达到合适的领会和复习模式,否则很容易在遇到长假休息时导致领会计划夭折。
Over
所有内容到这里就已经结束了,文末是一些优秀的参照文章和题单,希望能帮助大家在算法领会上少走一些弯路,最后祝大家学得开心~
巨人的肩膀
- 《Hello 算法》
- 《算法(第四版)》
- 《算法导论》
- 《数据结构与算法之美》
- GitHub - algorithms-sedgewick-wayne
- GitHub - LogicStack-LeetCode
- Github - LeetCode题单
- Leetcode - 论如何 4 个月高效刷满 500 题并形成长期记忆