瑕不掩瑜
我会这样定义一本我眼中的好书:深入浅出、关联丰富以及与我当下的认知水平相当。
这本小书的最大优点就在推理过程交代清楚。一步一步、为什么这么想、这么走,都给你描画得一清二楚。换言之,它是按照事物发展的逻辑顺序进行内容构建的,看得就很过瘾,像一本推理小说。
举例而言,它会在介绍完 SHA 算法后立刻介绍局部敏感的散列算法,在我刚在前一节中提出问题,如果我不想一点变动就让哈希值完全不同,那么应如何处理?它在下一节立刻垫上了,用 Simhash。这种逻辑上的完备与层层递进,就减少了很多理解成本。有时候你觉得理解困难,就是因为中间有步骤被抽去了,例如你在数学书里经常看到的:显然可得、易证得。
所以这是一本看起来很过瘾的小书。细嚼慢咽,给你剥出来最精华的内核。
但有一个错误我觉得是不该发生也不能被容忍的。在第七章,狄克斯特拉算法中,有明显错误。作者指出,狄只适用于有向无环图。而这是不正确的,事实上,只要没有负权边就可以。我在这里思路衔接不上,因为从算法实现中推不出作者言之凿凿的结果,最后经外部确认,才发现是作者出错。
看得出,作者对这个算法本身也理解不透彻。很多地方,没有讲透。例如在顶点选取上,为什么是选取当下可选点中,值最小的那个?因为在没有负权边的图中,它是已经被固定了的,因为要走其他任何一点再回到该顶点,都会造成值更大。而更新每个顶点的最小值,就是这个算法的核心,也是最机智、最动人、最美的地方。
也就是动态规划。前序的最优子结构,后面都可以直接拿来用,而且只要没有负权边,就满足无后效性的条件。但是作者既没有讲到上面那句缺失的话,让这个问题在我脑子里多思考了大半天,直到在另一本《我的第一本算法书》中才得到启发;也没有联系动态规划或者贪婪算法。或许略难,但是可以提一提,一带而过。
对了,这本书建议结合《我的第一本算法书》一起看,微信读书里也有,另外建议下载配套 app 一起使用方便理解,app 叫做 Algorithms。
因为这本书出版好些年了,这种硬伤还没有被更正,就让我不能接受。但是整体上瑕不掩瑜,是很好的入门书。况且它也给到学有余力的同学继续探索的空间。我非常喜欢他常常在篇末写的,如果你对这个话题感兴趣,欢迎你继续沿着某某算法的脚步朝里面研究。我非常喜欢这种引导。
最后,阅读算法书请配合力扣。我之所以会盛赞这本书,认为作者很多地方讲透了,就是因为很多章节我一看完,或者看了一半,就忍不住想开力扣开始刷相关标签的题目。动规、二分尤甚。这就是他把我讲明白了的最好说明。
最后的最后提醒自己,多找这类书看就够了,不要看鸡零狗碎的算法公众号,除非你能联系上作者能进一步沟通交流,不然直接读书才是最有效率的方式。出版书通常作了更好的排序工作,而且因为编辑的存在,错误也更少。
公号的错别字就够喝一壶,作者的自身理解不够,你看文章有如猜谜,更加难懂。