剑指Offer(专项突破版):数据结构与算法名企面试题精讲
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

前言

2021年1月22日,我从工作超过10年的微软离职,并将于25日入职一家相对而言规模要小很多的初创公司,开始一段新的职业旅程。

与所有程序员一样,换公司工作我也需要经历一轮又一轮的面试,而算法面试是面试中的重头戏。这次换工作的准备与面试阶段正好与本书的撰写阶段重合。在此之前,我作为面试官在微软已经面试了很多应聘者。在撰写本书的过程中,我结合自己多年来被他人面试及面试他人的经验,一直在思考如何高效地学习数据结构和算法,如何在面试短短的几十分钟内快速找到解题思路并写出高质量的代码。

以这十几年对程序员面试这个领域的观察,我的结论是面试的难度正在逐年增加,准备面试需要花费的时间和精力也越来越多。几年前如果听说谁为了准备面试刷了200道算法题,大家都会觉得非常惊讶。现在每个应聘者都在刷题,应届毕业生准备面试刷400道算法题基本上只能算是起步。由于应聘者刷题越来越熟练,因此程序员面试的标准自然也随之水涨船高。

我个人不喜欢也不建议采用题海战术。我们真正需要的是系统学习并深刻理解不同数据结构和算法的特征及适用场景。在真正掌握了每种数据结构及算法的精髓之后,如果针对典型的面试题进行必要的练习,在面试时就能以不变应万变,不管什么样的面试题都能迎刃而解。帮助读者系统学习并深刻理解不同数据结构和算法的特征及适用场景,是我撰写本书的初衷;帮助读者在算法面试过程中快速找到解题思路并写出高质量的代码,是我撰写本书的目的。

学习数据结构,需要先熟练掌握插入、删除和查找等基本操作,这些基本操作往往是解决很多面试题的关键。例如,如果我们熟练掌握了前缀树的插入和查找操作,那么很多与字符串前缀相关的问题都很容易解决。

同样,对于基础算法我们也需要深刻理解它们的原理及其实现代码。例如,二分查找通常只需要10行左右的代码就能实现,我们要理解它的循环条件的比较运算符什么时候用“<”,以及什么时候用“<=”,确定下一步查找前半部分或后半部分的标准是什么。在理解了这些原理之后,不管面试题如何变化,最终解决问题的代码都大同小异。

学习数据结构,还要深刻理解每种数据结构的特点及其适用场景,这样才能在面试过程中合理选择数据结构解决问题。例如,哈希表是时间效率非常高的数据结构,它的插入、删除和查找操作的时间复杂度都是O(1)。虽然哈希表的时间效率非常高,但并不是所有的问题都能用哈希表来解决。如果存储的元素是字符串,并且需要根据字符串的前缀进行查找,那么前缀树是更好的选择。如果存储的元素是数值,并且解决问题需要知道数据集合中的最大值或最小值,那么堆可能是更好的选择。如果需要对动态数据集合排序,并且需要根据数值的大小进行查找,那么平衡的二叉搜索树(Java中的TreeSet或TreeMap)可能是更好的选择。

同样,学习算法也要理解每种算法的特点及其适用场景。例如,回溯法和动态规划适合解决的问题看起来很类似。如果解决一个问题需要多个步骤,并且每个步骤都面临多个选择,那么我们可以考虑使用回溯法或动态规划来解决问题。如果要求列举出问题所有的解,那么我们应该采用回溯法来解决问题。如果只是要求计算某个最优解(通常是最大值或最小值)或计算解的数目,那么我们应该采用动态规划来解决问题。

本书的关注点是算法面试,因此,和常规的算法类书籍相比,本书更加注重面试准备的实用性。本书注重总结常用的解题思路。例如,如果面试题提到与二叉树相关的概念,那么我们可以尝试用广度优先搜索算法来解决这个问题。本书的“解题小经验”条目总结了常用的解题思路,建议读者留意。

本书还着重总结了一些常用的代码模板,希望读者能够理解这些代码模板的来龙去脉,这样在面试过程中如果遇到类似的问题就能套用相应的模板来解决,轻松做到举一反三。例如,用并查集解决问题时合并和查找操作的代码大同小异,在合适的时候套用函数union和findFather就能解决很多与图相关的问题。

在撰写本书的过程中我得到了很多朋友的帮助。类似于程序员在递交代码之前需要通过代码审查,在将书稿交付给出版社编辑修改、排版之前,我邀请了很多朋友帮忙审阅,其中包括微软的陈黎明、贾志勇、王洪臣、高天翔、袁源、李兴华,谷歌的田超,脸书的董朝、何涛,苹果的吴斌,阿里巴巴的韩伟东、殷焰,字节跳动的尹彦,以及诺基亚贝尔的吴永康等。他们仔细审阅了书稿并提出大量建议,大幅度提高了本书的质量。在此谨向他们表示由衷的感谢。

当然,我的时间和能力有限,书中难免存在一些疏漏之处。如果读者发现书中的问题,请通过电子邮件(zhedahht@hotmail.com)和我联系。

感谢电子工业出版社的工作人员,尤其是张春雨的帮助。他们大到全书的架构,小到文字的推敲,都给予了我极大的帮助,从而使本书的质量得到了极大的提升。

本书还得到了很多朋友的支持和帮助,由于篇幅有限,在此不一一列举,但我一样对他们心存感激。

最后,我要衷心地感谢我的爱人刘素云。感谢她多年来对我的理解和支持,为我营造了一个温馨而又浪漫的家,让我能够静下心来读书和写作。我也同样感谢我们两个可爱的儿子,他们脸上纯真、灿烂的笑容是我每天工作的动力。我无以为谢,谨以此书献给他们。

何海涛

2021年1月24日于西雅图

读者服务

微信扫码回复:41520

● 获取本书配套代码及习题在线练习地址

● 获取力扣(LeetCode)Plus会员专享折扣

● 加入本书读者交流群,与本书作者互动

● 获取【百场业界大咖直播合集】(永久更新),仅需1元