李春葆,计算机学院教授,主要研究方向:数据挖掘、人工智能和软件工程。发表论文30余篇,主持和参加多项科研课题。著作教材多部。从事近30年C/C++语言、数据结构和算法设计等课程的第一线本科教学工作,具备丰富的教学经验,曾参与深圳名企的笔试和面试题库建设。
本书旨在帮助读者更好地应对算法面试,提高算法和编程能力。书中按专题精选了LeetCode平台的一系列的热点算法题,并详细解释其求解思路和过程。全书分为三个部分,第Ⅰ部分为数据结构及其应用,以常用数据结构为主题,深入讲解各种数据结构的应用方法和技巧。第Ⅱ部分为算法策略及其应用,以基本算法设计方法和算法设计策略为主题,深入讲解各种算法设计策略的应用方法和技巧。第Ⅲ部分为经典问题及其求解,以实际中的一些问题为主题,深入讲解这些问题多种求解方法。
本书适合于需要进行算法面试的读者,通过阅读本书可以掌握算法面试中求解问题的方法和技巧,提升自己的算法技能和思维方式,从而在面试中脱颖而出。同时可以作为《数据结构》和《算法设计与分析》课程的辅导书,也可以供各种程序设计竞赛和计算机编程爱好者研习。
目录
李春葆,计算机学院教授,主要研究方向:数据挖掘、人工智能和软件工程。发表论文30余篇,主持和参加多项科研课题。著作教材多部。从事近30年C/C++语言、数据结构和算法设计等课程的第一线本科教学工作,具备丰富的教学经验,曾参与深圳名企的笔试和面试题库建设。
本书适合于需要进行算法面试的读者,通过阅读本书可以掌握算法面试中求解问题的方法和技巧,提升自己的算法技能和思维方式,从而在面试中脱颖而出。同时,本书可以作为“数据结构”和“算法设计与分析”课程的辅导书,也可以供各种程序设计竞赛和计算机编程爱好者研习。
党的二十大报告指出: 教育、科技、人才是全面建设社会主义现代化国家的基础性、战略性支撑。必须坚持科技是第一生产力、人才是第一资源、创新是第一动力,深入实施科教兴国战略、人才强国战略、创新驱动发展战略,开辟发展新领域新赛道,不断塑造发展新动能新优势。高等教育与经济社会发展紧密相连,对促进就业创业、助力经济社会发展、增进人民福祉具有重要意义。
在现代社会中,算法已经广泛应用于计算机科学的各个领域,如人工智能、数据挖掘、网络安全和生物信息学等。许多成功的案例都证明了算法的重要性和实用性,如搜索引擎的优化、社交网络的推荐系统、医疗诊断的辅助决策等。算法知识和技能对于程序员来说至关重要。算法面试是许多科技公司招聘过程中必不可少的一环,它考查的是候选人的编程能力、思维逻辑、问题解决能力以及算法设计技巧。通过算法面试,候选人可以展示自己的技能和知识,提升自己在求职市场上的竞争力。
LeetCode是一个在线刷题平台,提供了大量的算法题目供用户练习,帮助用户加深对数据结构与算法的理解和掌握。LeetCode于2011年诞生于美国硅谷,2018年2月由上海领扣网络引入中国并正式命名为力扣,其中文网站于同月测试上线,2018年10月力扣全新改版,更加注重于学习体验。许多北美大厂(如谷歌、微软和亚马逊等)在面试中都涉及算法及其相关知识,甚至直接从LeetCode出题(许多北美程序员从实习到全职,再到跳槽,一路上都在刷LeetCode)。国内大厂近几年也越来越重视对算法的考查,如腾讯、百度、华为和字节跳动等都是较看重算法面试的公司。
本书提供一系列编者精心挑选的LeetCode问题,覆盖不同难度级别和C++/Python编程语言,旨在帮助读者提高编程技能和更深入地理解数据结构与算法的原理,以应对算法面试中的挑战。
本书内容
本书共25章,分为三部分。
第一部分(第1~14章)为数据结构及其应用,以常用数据结构为主题,深入讲解各种数据结构的应用方法和技巧,包含数组、链表、栈、队列和双端队列、哈希表、二叉树、二叉搜索树、平衡二叉树、优先队列、并查集、前缀和与差分、线段树、树状数组、字典树和后缀数组等。
第二部分(第15~22章)为算法设计策略及其应用,以基本算法设计方法和算法设计策略为主题,深入讲解各种算法设计策略的应用方法和技巧,包含穷举法、递归、分治法、DFS、BFS和拓扑排序、回溯法、分支限界法、A*算法、动态规划和贪心法等。
第三部分(第23~25章)为经典问题及其求解,以实际面试中的一些问题为主题,深入讲解这些问题的多种求解方法,对比分析不同方法的差异,包含跳跃问题、迷宫问题和设计问题等专题。
本书特色
(1) 全面覆盖: 本书对算法面试中可能涉及的各种主题进行了较为全面的覆盖,包括各种基础数据结构和常用的算法设计策略。
(2) 实战导向: 书中精选的许多LeetCode题目都是国内外互联网大厂的热门算法面试题,具有很强的实战性。
(3) 知识的结构化: 本书以数据结构和算法策略为主线,划分为若干知识点,通过实例和问题求解将相关的知识点串起来构成知识网络,不仅可以加深读者对算法原理的理解,而且可以拓宽读者对算法应用的视野。
(4) 求解方法的多维性: 同一个问题采用多种算法策略实现,如迷宫问题采用回溯法、分支限界法、A*算法和贪心法求解等。通过对不同算法策略的比较,使读者更容易体会每种算法策略的设计特点和优缺点,以提高算法设计的效率。
(5) 代码的规范化: 书中代码采用C++和Python语言编写,不仅在LeetCode平台上提交通过,而且进行了精心的代码组织和规范化,包括变量名称和算法策略的统一与标准化等,尽可能提高代码的可读性。
注: 书中以LeetCode开头+序号的题目均来自LeetCode平台。
配套资源获取方式
扫描封底的文泉云盘防盗码,再扫描目录上方的二维码获取。
如何刷题和使用本书
在互联网上和力扣平台上有许多关于LeetCode刷题经验的分享,读者可以酌情参考。编者建议读者在具备一定的数据结构和算法基础后按本书中的专题分类刷题,先刷数据结构部分后刷算法部分,先刷简单题目后刷困难题目(书中题目按难度分为3个级别,即★、★★和★★★,分别对应简单、中等和困难),在刷题时要注重算法思路和算法实现细节,每个环节都要清清楚楚,并能够做到举一反三,同时将自己在线提交的结果与书中的时间和空间进行对比分析(值得注意的是书中列出的时间和空间是编者提交的结果,后面因环境的变化可能有所不同)。另外,经常进行归纳总结和撰写解题报告是提高编程能力的有效手段。在没有对一道题目进行深入思考和分析之前就阅读书中的代码部分甚至是复制、粘贴代码,这种做法不可取。总之,使用良好的刷题方法并且持之以恒,一定会收获理想的效果。
致谢
本书以LeetCode为平台,书中所有LeetCode题目及其相关内容都得到领扣网络(上海)有限公司的授权。本书的编写得到清华大学出版社魏江江分社长的大力支持,王冰飞老师给予精心编辑。本书在编写过程中参考了众多博客和LeetCode题解评论栏目的博文,编者在此一并表示衷心的感谢。
作者
2024年8月
第二部分算法设计策略及其应用
第15章穷举法
15.1穷举法概述
15.1.1什么是穷举法
15.1.2顺序列举设计方法
15.1.3组合列举设计方法
15.1.4排列列举设计方法
15.2顺序列举的算法设计
15.2.1LeetCode485——1的最多连续个数★
15.2.2LeetCode1464——数组中两个元素的最大乘积★
15.2.3LeetCode829——连续整数求和★★★
15.2.4LeetCode17——电话号码的字母组合★★
15.2.5LeetCode845——数组中的最长山脉★★
15.2.6LeetCode209——长度最小的子数组★★
15.2.7LeetCode134——加油站★★
15.3组合列举的算法设计
15.3.1LeetCode78——子集★★
15.3.2LeetCode90——子集Ⅱ★★
15.3.3LeetCode77——组合★★
15.3.4LeetCode1863——求出所有子集的异或总和再求和★
15.4排列列举的算法设计
15.4.1LeetCode46——全排列★★
15.4.2LeetCode60——排列序列★★★
15.4.3LeetCode52——n皇后Ⅱ★★★
推荐练习题
第16章递归
16.1递归概述
16.1.1递归的定义
16.1.2递归模型
16.1.3递归的执行过程
16.1.4递归算法的设计
16.1.5使用递归的注意事项
16.2基于递归数据结构的递归算法设计
16.2.1LeetCode2487——从链表中移除结点★★
16.2.2LeetCode21——合并两个有序链表★
16.2.3LeetCode814——二叉树的剪支★★
16.2.4LeetCode236——二叉树的最近公共祖先★★
16.2.5LeetCode114——将二叉树展开为链表★★
16.3基于归纳的递归算法设计
16.3.1LeetCode17——电话号码的字母组合★★
16.3.2LeetCode191——位1的个数★
16.3.3LeetCode231——2的幂★
16.3.4LeetCode394——字符串解码★★
推荐练习题
第17章分治法
17.1分治法概述
17.1.1什么是分治法
17.1.2二分查找及其扩展算法
17.2基本分治算法设计
17.2.1LeetCode169——多数元素★
17.2.2LeetCode53——最大子数组和★★
17.2.3LeetCode241——为运算表达式设计优先级★★
17.2.4LeetCode95——不同的二叉搜索树Ⅱ★★
17.3快速排序和二路归并排序应用的算法设计
17.3.1LeetCode912——排序数组★★
17.3.2LeetCode215——数组中第k大的元素★★
17.3.3LeetCode315——计算右侧小于当前元素的个数★★★
17.3.4LeetCode493——翻转对★★★
17.4二分查找应用的算法设计
17.4.1LeetCode69——x的平方根★
17.4.2LeetCode167——有序数组中的两数之和Ⅱ★★
17.4.3LeetCode74——搜索二维矩阵★★
17.4.4LeetCode4——寻找两个正序数组的中位数★★★
17.4.5LeetCode744——寻找比目标字母大的最小字母★
17.4.6LeetCode153——寻找旋转排序数组中的最小值★★
17.4.7LeetCode33——搜索旋转排序数组★★
17.4.8LeetCode81——搜索旋转排序数组Ⅱ★★
17.4.9LeetCode315——计算右侧小于当前元素的个数★★★
17.4.10LeetCode493——翻转对★★★
17.4.11LeetCode215——数组中第k大的元素★★
17.4.12LeetCode378——有序矩阵中第k小的元素★★
17.4.13LeetCode410——分割数组的最大值★★★
17.4.14LeetCode1011——在D天内送达包裹的能力★★
推荐练习题
第18章DFS、BFS和拓扑排序
18.1DFS、BFS和拓扑排序概述
18.1.1深度优先搜索
18.1.2广度优先搜索
18.1.3拓扑排序
18.2深度优先遍历应用的算法设计
18.2.1LeetCode200——岛屿的数量★★
18.2.2LeetCode463——岛屿的周长★
18.2.3LeetCode130——被围绕的区域★★
18.2.4LeetCode529——扫雷游戏★★
18.2.5LeetCode365——水壶问题★★
18.2.6LeetCode332——重新安排行程★★★
18.3广度优先遍历应用的算法设计
18.3.1LeetCode200——岛屿的数量★★
18.3.2LeetCode130——被围绕的区域★★
18.3.3LeetCode529——扫雷游戏★★
18.3.4LeetCode365——水壶问题★★
18.3.5LeetCode1162——地图分析★★
18.3.6LeetCode847——访问所有结点的最短路径★★★
18.3.7LeetCode2608——图中的最短环★★★
18.3.8LeetCode2204——无向图中到环的距离★★★
18.3.9LeetCode127——单词接龙★★★
18.3.10LeetCode934——最短的桥★★
18.4拓扑排序应用的算法设计
18.4.1LeetCode1462——课程安排Ⅳ★★
18.4.2LeetCode802——找到最终的安全状态★★
18.4.3LeetCode269——火星词典★★★
推荐练习题
第19章回溯法
19.1回溯法概述
19.1.1什么是回溯法
19.1.2回溯法的算法设计
19.2子集树的回溯算法设计
19.2.1LeetCode78——子集★★
19.2.2LeetCode77——组合★★
19.2.3LeetCode40——组合总和Ⅱ★★
19.2.4LeetCode39——组合总和★★
19.2.5LeetCode90——子集Ⅱ★★
19.2.6LeetCode216——组合总和Ⅲ★★
19.2.7LeetCode491——递增子序列★★
19.2.8LeetCode131——分割回文串★★
19.2.9LeetCode93——复原IP地址★★
19.2.10LeetCode282——给表达式添加运算符★★★
19.2.11LeetCode22——括号的生成★★
19.2.12LeetCode301——删除无效的括号★★★
19.2.13LeetCode17——电话号码的字母组合★★
19.2.14LeetCode79——单词的搜索★★
19.2.15LeetCode797——所有可能的路径★★
19.2.16LeetCode332——重新安排行程★★★
19.2.17LeetCode37——解数独★★★
19.2.18LeetCode679——24点游戏★★★
19.2.19LeetCode1723——完成所有工作的最短时间★★★
19.3排列树的回溯算法设计
19.3.1LeetCode46——全排列★★
19.3.2LeetCode47——全排列Ⅱ★★
19.3.3LeetCode60——排列序列★★★
19.3.4LeetCode51——n皇后★★★