1.开篇(指导手册&复杂度分析)
《数据结构与算法之美》学习指导手册
1.复杂度分析
掌握程度:自行分析专栏中大部分的数据结构和算法的时间、空间复杂度
2.数组、栈、队列
掌握程度:能自己实现动态数组、栈、队列
3.链表
掌握程度:能轻松写出经典链表题目代码
4.递归
理论知识不多,主要是多练。
简单:斐波那契数列、求阶乘;
中等:归并排序、快速排序、二叉树的遍历、求高度;
复杂:回溯八皇后、背包问题
掌握程度:轻松写出二叉树遍历、八皇后、背包问题、DFS的递归代码
5.排序、二分查找
掌握程度:能自己把各种排序算法、二分查找及其变体代码写一遍
6.跳表
掌握程度:看懂专栏内容即可,不需要掌握代码实现
7.散列表
掌握程度:对于初学者,自己实现一个拉链法解决冲突的散列表即可
8.哈希算法
掌握程度:简单
9.二叉树
在面试中经常会被考到,所以要重点掌握。
掌握程度:能代码实现二叉树的三种遍历算法、按层遍历、求高度等经典二叉树题目
10.红黑树
掌握程度:初学者不要把时间浪费在这上面。
11~20:待补充...
01 - 为什么要学习数据结构和算法?
想要通关大厂面试,千万别让数据结构和算法拖了后腿
业务开发工程师,你真的愿意做一辈子CRUD boy吗
基础架构研发工程师,写出达到开源水平的框架才是你的目标
对编程还有追求,不想被行业淘汰?那就不要只会写凑合能用的代码!
02 - 如何抓住重点,系统高效地学习数据结构与算法?
学习的重点在什么地方?
首先要掌握一个数据结构与算法中最重要的概念-复杂度分析。
它几乎占了数据结构与算法这门课的半壁江山,是数据结构和算法学习的精髓。
复杂度分析,需要花大力气来啃,必须要拿下,并且要搞的非常熟练。
如果不分重点地学习,眉毛胡子一把抓,学起来肯定会比较吃力。
20个最常用的、最基础的数据结构与算法,不管是应付面试还是工作需要,只要集中精力逐一攻克这20个知识点就足够了。
10个数据结构:
数组、链表、栈、队列、二叉树、散列表、堆、跳表、图、Trie树
10个算法:
递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配
学习数据结构与算法的过程,是一个非常好的思维训练的过程,所以,千万不要被动的记忆,要多辩证地思考,多问为什么。
一些可以让你事半功倍的学习技巧
1.边学边练,适度刷题
边学边练,这一招非常有用。建议每周花1-2个小时的时间,集中把这周的三节内容涉及的数据结构与算法,全都自己写出来,用代码实现一遍。
可以适度刷题,但一定不要浪费太多时间在刷题上。
2.多问、多思考、多互动
3.打怪升级学习法(设定目标)
4.知识需要沉淀,不要想试图一下子掌握所有
学习知识的过程是反复迭代、不断沉淀的过程。
03 - 复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?
复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。
为什么需要复杂度分析?
通过统计、监控得到算法执行的时间和占用的内存大小,称为”事后统计法“,有非常大的局限性。
1.测试结果非常依赖测试环境
2.数据结果受数据规模的影响很大。
我们需要一个不用具体的测试数据来测试,就可以粗略估算执行效率的方法。
大O时间复杂度表示法,并不具体表示代码真正的执行时间,而是代表代码执行时间随数据规模增长的变化趋势。
当n很大时,公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略。我们只需要记录一个最大量级就可以了。
时间复杂度分析
1.只关注循环执行次数最多的一段代码
2.加法法则:总复杂度等于量级最大的那段代码的复杂度
O(1)+O(n)+O(n²)=O(n²)
3.嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
复杂度分析这个东西关键在于”熟练“
几种常见时间复杂度实例分析
复杂度量级(按数量级递增)
多项式量级:O(1)、O(logn)、O(n)、O(nlogn)、O(n²)、O(n³)...
非多项式量级:指数阶O(2^n)、阶乘阶O(n!)—>非常低效
O(1)
O(logn)、O(nlogn)
O(nlogn),相当于是循环执行n遍logn的代码。比如,归并排序、快速排序的时间复杂度都是O(nlogn)
O(m+n)、O(m*n)
O(m+n),我们无法评估m和n谁的量级更大时,就不能简单地利用加法法则省略掉其中一个。
加法法则就失效了。但是乘法法则**O(m*n)**还是有效的。
04 - 复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度
最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度。
最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度。
平均时间复杂度:加权平均复杂度,或者期望时间复杂度,将各种情况发生的概率考虑进去。
在大多数情况下,我们并不需要区分最好、最坏、平均情况时间复杂三种情况。
均摊时间复杂度应用的场景更加特殊,更加有限。
看是否能将较高时间复杂度的那次操作的耗时,平摊到其他那些时间复杂度比较低的操作上。而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度,就等于最好情况时间复杂度。
均摊时间复杂度就是一种特殊的平均时间复杂度,我们没必要花太多精力去区分它们。