算法与复杂度

前言

这个系列的博文会逐个介绍计算机科学里面最基础、也是最重要的一部分内容:算法(algorithm)。提到它,这可能是你最擅长的部分,亦或是你学生生涯的噩梦。不管怎么样,对于学计算机的小伙伴来讲,它始终是不可回避的一个话题。不论是学生时代的你还是已经踏上了工作的岗位,算法都会一直陪伴着你。

为什么要做这个系列呢?因为网上对于这一块的内容实在是太多,甚至是太杂,而很少有把算法的知识体系整合起来形成一个系列的教学博客。于是乎想尽自己的微薄之力,让更多的人能够更好地理解算法,不畏惧算法,在未来求职的面试中不再因为它而与自己理想的公司失之交臂。

我将有别于国内的教学方式和教学内容。形式上不再是只针对如何解决这个问题,因为只会解决问题并不代表真正理解这个问题。我会花一些篇幅着重介绍一些概念性的内容,这也是国内的教学最欠缺的部分。国内的课堂不会告诉你自然对数 e 揭示了自然界生长的规律;学完了线性代数,你可能光学会了如何解行列式,却忽视了行列式也是有几何意义的。在内容上我不再按照“排序算法”、“搜索算法”等方式分类,而采用了解决问题的不同方式来划分,比如“暴力求解”、“分治法”、“动态规划”等等。整个系列我以 Levin 编写的 Introduction to The Design and Analysis of Algorithms, 3rd Edition 作为参考。要是你觉得这本书讲得太基础,你也可以参考 MIT 的《算法导论》,绝对的算法界的权威书籍。

编程语言我会采用 Python,因为 Python 是最接近这些英文书里伪代码,理解起来会更加方便。对于刚入门的小白来讲,Python 的简洁不会让你因为不能理解编程语言本身而最终放弃了这门课程的学习。我会把每一节的内容的完整代码都放在我的 GitHub 的 Algorithm 仓库里,方便学习后用代码真正实现它们。

最后,要是讲解有任何疑问,欢迎在评论区留言。如果发现了有任何错误和表述不规范的地方,希望各位大佬轻喷,毕竟我也是第一次写博客,有错误也是在所难免的哈。

总览

介绍 (Introduction)

1.1 什么是算法

基本知识 (Basic Knowledge)

2.1 基本数据结构
2.2 算法的问题类型

复杂度分析 (Complexity Analysis)

3.1 三种表示方法:O, Ω, Θ
3.2 复杂度分析(非递归)
3.3 复杂度分析(递归)

暴力求解 (Brute Force)

4.1 冒泡排序与选择排序
4.2 字符串匹配(BF)
4.3 图的两种遍历
4.4 最近点对与凸包问题(BF)
4.5 暴力搜索

减治法(Decrease and Conquer)

5.1 插入排序
5.2 拓扑排序
5.3 二分查找与二叉树
5.4 插值查找

分治法(Divide and Conquer)

6.1 归并排序
6.2 快速排序
6.3 二叉树的遍历
6.4 最近点对与凸包问题(DC)

变治法(Transform and Conquer)

7.1 预排序
7.2 霍纳法则
7.3 堆与堆排序
7.4 AVL树
7.5 红黑树
7.6 2-3树

时空权衡(Time Space Tradeoff)

8.1 计数排序
8.2 字符串匹配(TST)
8.3 哈希

动态规划(Dynamic Programming)

9.1 关于钱的两个经典问题
9.2 背包问题(DP)
9.3 弗洛伊德算法

贪心算法(Greedy Algorithm)

10.1 普林姆算法
10.2 克鲁斯卡尔算法
10.3 迪克斯特拉算法
10.4 哈弗曼树

*高阶算法(Advanced Algorithm)

*回溯
*分支限界
*千禧问题:P = NP ?