Skip to content

Latest commit

 

History

History
316 lines (212 loc) · 20.2 KB

数据结构和算法学习路线 by 程序员鱼皮.md

File metadata and controls

316 lines (212 loc) · 20.2 KB

数据结构和算法学习路线 by 程序员鱼皮

本文作者:程序员鱼皮

本站地址:https://codefather.cn

为什么数据结构和算法如此重要?因为:程序 = 数据结构 + 算法

数据结构是一组数据的存储结构和组织方式,使得该组数据便于访问、修改、存储。

算法是操作数据的一组方法,解决问题的一系列步骤。

学习的必要性

有些同学可能会因为平时写代码用不到数据结构和算法,就认为它们不重要,这是**一个错误的认识 **!

其实很多时候,并不是用不到,而是因为你欠缺了一部分知识后,根本就想不到去用它来优化你的程序,比如提高性能、节省内存等。

还有一个平时很少用到算法的原因是:其他开发者给你封装好了。但假如有一天,你用的框架或算法库出了问题、或者某个算法效率低下,需要你来优化的时候,如果没学过数据结构和算法你大概率是搞不定的。

换句话说,不是不报,是时候未到。学好算法和数据结构,有助于开拓我们的思路,改变我们思考问题的方式,提高我们的问题解决能力(公司最看重的也是这点)。

至少我觉得,学习数据结构和算法让我受益匪浅。

学习条件

  1. 必须要学过至少一门编程语言
  2. 需预留至少 2 个月的空余时间,急着找工作的同学可以先不学

什么时候学数据结构和算法?

时间足够的话,我个人建议 **学完一门编程语言后 **就可以开始刷算法了。一方面是因为算法真的是太重要了;另一方面是用 Java 刷算法还能巩固一下语法基础,避免出现纸上谈兵、后面做项目时因为不熟悉语法导致写不出代码的情况。

完全零基础的话,数据结构和算法不是面试前短短几周就能准备过来的(除非你很聪明)。鱼皮是从大二上开始跟着学校学习数据结构(虽然我没怎么听课,是靠后面自己看书补回来的),并且从大二暑假开始刷题,一年多的时间总共刷了 1000 多道算法题。因为自己准备得早,所以学得还算比较扎实,面试时遇到的算法题目基本都能答出来;也是因为准备得早,每天的压力没那么大。

大纲

思维导图文件: 数据结构和算法学习路线 by 程序员鱼皮

知识

  • 数据结构
    • 线性结构
      • 数组
        • 字符串
      • 链表
        • 单向链表
        • 双向链表
        • 循环链表
      • 队列
        • 普通队列
        • 双端队列
    • 散列结构
      • 集合
      • 映射
      • BitMap
      • 二叉树
      • 二叉查找树
      • 多叉树
      • 前缀树
        • 小顶堆
        • 大顶堆
      • 最短路径
      • 并查集
      • 最小生成树
      • 拓扑排序
  • 算法
    • 排序
      • 冒泡排序
      • 快速排序
      • 插入排序
      • 希尔排序
      • 选择排序
      • 堆排序
      • 归并排序
      • 计数排序
      • 桶排序
      • 基数排序
    • 贪心
    • 分治
    • 动态规划
    • 递归
    • 回溯
    • 枚举
    • 查找
      • 有序表查找
        • 二分查找
      • 线性表查找
      • 树结构查找
      • 散列表查找
    • 搜索
      • 深度优先搜索 DFS
      • 广度优先搜索 BFS
    • 字符串匹配
      • KMP
      • 前缀树
    • 位运算
  • 复杂度分析
    • 时间复杂度
    • 空间复杂度

学习建议

  1. 数据结构和算法不可追求速成(学得快忘得快),而是应该每天坚持刷 2 道以上的题目保持手感。(可以在编程导航中打卡分享自己每天所刷的题目,也许会有小伙伴和你一起讨论哦)
  2. 自己在写算法题目时,要给代码多写一些注释,记录自己当时的思考,并且做过的每道算法题目的代码都要分类保存好,便于自己复习。
  3. 可以根据实际情况自己写一些题解,写题解的过程中,不仅能检验自己是否真的理解,还能再次巩固、帮助自己复习。
  4. 算法是一种思想,用任何你正在学习或者熟悉的编程语言来写代码均可,可以帮助你复习编程语言的语法和细节。
  5. 不用因为担心自己算法不够而不敢面试,只要你有了基本的开发技能就足够了,算法可以持续强化。
  6. 很多同学可能会习惯性地刷自己觉得很简单的题目,而对于中等 / 困难的题目有恐惧感,下意识地回避。这在刚开始入门时没什么问题,但如果已经刷了几百题,不要满足于自己会的知识,要适当挑战,走出舒适圈。
  7. 有时间的朋友也可以试着参与各种算法竞赛和考证书,比如蓝桥杯、PAT 认证、LeetCode 周赛等。这些比赛没什么门槛,难度也没有 ACM 那么高。可以帮助你集中精神高效做题、提前适应面试的节奏感。

学习路线

本学习路线适用于所有从 0 开始学算法的同学,但如果是要搞 ACM 算法竞赛的话,只学这些是远远不够的哦。

预热

该阶段可跳过,或者与之后的阶段同时进行

初学编程、刚开始学习算法时,可以先通过阅读课外书、科普视频来培养兴趣,简单地入门,而不要求真正的理解。

推荐阅读《漫画算法:小灰的算法之旅》 ,轻松幽默。

依次学习

了解每个数据结构和算法的概念、特点、适用场景、时空复杂度,并且能够自己写代码从 0 到 1 实现一遍每个数据结构和算法。注意要按顺序学习,而不是一次性看完所有的数据结构和算法后才再回过头来写代码!

要重点学的知识点基本就是大纲中提到的那些,图论这一块了解即可,优先级不高,面试考的也不多。链表、树是面试重点。

推荐直接从 LeetCode 的学习板块 LeetBook 开始刷起,边学边写代码,学的更扎实。

学习顺序

  1. 算法基础理论和复杂度分析:https://www.bilibili.com/video/BV1nJ411V7bd(看前几节就可以了,后面可以配合着 LeetCode 去看,依次攻克每个知识点)
  2. 数组和字符串:https://leetcode-cn.com/leetbook/detail/array-and-string/
  3. 链表:https://leetcode-cn.com/leetbook/detail/linked-list/
  4. 队列 & 栈:https://leetcode-cn.com/leetbook/detail/queue-stack/
  5. 哈希表:https://leetcode-cn.com/leetbook/detail/hash-table/
  6. 查找表类算法:https://leetcode-cn.com/leetbook/detail/all-about-lockup-table/
  7. 二分查找:https://leetcode-cn.com/leetbook/detail/binary-search/
  8. 二叉树:https://leetcode-cn.com/leetbook/detail/data-structure-binary-tree/
  9. 二叉搜索树:https://leetcode-cn.com/leetbook/detail/introduction-to-data-structure-binary-search-tree/
  10. 前缀树:https://leetcode-cn.com/leetbook/detail/trie/
  11. N 叉树:https://leetcode-cn.com/leetbook/detail/n-ary-tree/
  12. 数组类算法:https://leetcode-cn.com/leetbook/detail/all-about-array/
  13. 初级算法:https://leetcode-cn.com/leetbook/detail/top-interview-questions-easy/
  14. 中级算法:https://leetcode-cn.com/leetbook/detail/top-interview-questions-medium/

完整教程

辅助学习的工具

依次练习

学完某个数据结构和算法后,立刻趁热打铁去做几道相关的题目。

每道题目给自己一个时间限制,超出时间后就直接去阅读题解(建议看带有图片和动画演示的题解),有一些思路后再试着自己去做题,直到把题目完成写出,并且要真正理解每道题目的解法。

即使是自己做出的题目,也建议去看下其他同学的题解,多积累一种方法。

刷题

当把每个知识点学完一遍后,可以去 LeetCode 网站的题库中刷题,按照难易度、通过率、热门程度每天坚持刷几道。时间紧张(三个月内)的话也可以直接去刷热门题目集合。

有时间的话,建议大家可以参加 蓝桥杯竞赛 、考 PAT 认证,检验自己的学习、丰富自己的简历。

刷题顺序

仅供参考,可以有自己的学习方法和习惯

  1. 先按知识点逐个去刷,可以进入 https://leetcode-cn.com/leetbook/,这里有按知识点分类的教程和题目,比如初级算法、数组、字符串、队列、栈、树等等。每刷完一个知识点,可以再做几道相关的题目,举一反三,每道题目都要做到 100% 通过。
  2. 把所有知识点逐个刷完后,可以再按照难度、通过率去自由刷题,刷大概几十道简单题目后,可以去做 LeetCode 热题 100 道:https://leetcode-cn.com/problem-list/2cktkvj/。当然,时间紧迫的话,也可以直接刷热题。
  3. 算法最好刷 200 道题以上,每天 2 - 3 道,坚持 2 个月以上,并且还要整理好自己的代码、定期复习。尽量不要去刷冷门的题目!别逞能去刷那么多 Hard 题,性价比不高,不如省点时间去做项目。
  4. 刷完 LeetCode 经典题目后,可以去刷刷《剑指 Offer》或者《剑指 Offer 面试精装版》进行巩固。

相关资源

面试前

在面试前,建议刷一遍 LeetCode 热门题目,有时间的话还可以阅读《剑指 Offer》、《剑指 Offer 专项突破版》、《程序员代码面试指南》等书籍,争取面试时撞到原题。

几份完整的题解

有空的话挑一份看即可

如果有意向公司(比如大厂)的话,可以去刷一下 历年笔试题目 (难度可能比较大,不要因此丧失信心,多练习后就习惯了)。

工作后

工作之后,如果有兴趣的话,可以通过刷题来帮助自己巩固编程语言、提升思维能力。

更多学习建议

1、刷题顺序

最直接的就是按照知识点标签选题,从【简单的】题目刷起,从【通过率高】的题目刷起,循序渐进。

2、养成自己的刷题习惯

的确,学算法是枯燥的,想长期坚持非常难,像鱼皮当时刷了 1000 多道不同平台的题目,现在回过头来都觉得不可思议。

分析下我能够坚持刷这么多题的原因,主要是因为养成了自己的刷题习惯,把刷算法当成了像刷牙洗脸一样的日常任务。

怎么养成自己的刷题习惯呢?

1)每天在固定的时间学习算法。比如我当时每天早上 6 点多就会躺在床上思考没解决的算法题,想到方案后就会拿个枕头靠在床上敲代码做题,其实都有点魔怔了哈哈。

2)给自己定每日的学习目标。比如我每天会花 1 个半小时左右完成 3 道题目,不多也不少。如果没做完,就等其他工作完成后再静下心来思考;如果超前达到目标,那么可以奖励自己一顿番茄炒蛋。

3)分享自己的学习记录。比如我当时每刷几十道题目,就会跟朋友小小 “炫耀” 一下,看着自己的打卡表越来越满,也会有不小的成就感。

3、找到自己的灯塔

如果一个人学算法觉得很累,那么就一定要找到能伴你共同前行的伙伴,或者给你指路的灯塔。

可能是和你一起努力刷题的伙伴,可能是一个算法交流圈子,可能是一位专业的算法导师。

说不定一个问题你自己思考 30 分钟还没办法解决,而请教他人 5 分钟就能解决了,能大大节约你的时间。

至于一些三天打鱼两天晒网、动不动就摆烂的人,还是敬而远之。

4、学会总结

解决学算法学了就忘的最好方法,就是多记录总结,把知识沉淀成电子文档,而不是全部装在大脑里。

不要觉得写总结很麻烦,记录自己的解题思路、或者在代码上补充详细的注释都是可以的。如果你连自己的思路都表述不清楚,那么说明这道题你就没有理解!打回去重做!

可以通过云文档、GitHub 仓库、或者各平台的发帖来总结分享自己的题解和心得,费曼学习法,能够给别人讲清楚题目的做法,你自己的印象就会更深刻。

这样做了之后,哪怕刷了算法就忘,也能快速通过自己的笔记总结捡起来当时的思路,大幅提高复习效率。

5、利用题解

LeetCode 平台的每道题目都有很多小伙伴给出了题解,讲述如何解决这道题。

怎么才算利用好题解呢?

首先,读题解包括两个部分,读思路读代码,既要理解作者做题的思路和逻辑,也要细致入微地学习他人代码中优秀的写法。即使这道题目你做出来了,击败 100% 了,我也建议去看看别人的题解,学习更多他人解题的思路,帮助自己打开脑洞,做到 一题多解

话说,现在网上的题解实在是太多啦!在刷题时,读个一两份就行了,别给自己太大压力。

除了看题解外,很多同学没有意识到,多写题解 才是真正的法宝,把自己的解题思路整理成文,或者讲给别人听。这样做不仅能够加深自己对题目的印象,进一步加深对算法的理解,帮助自己回顾解题过程,从而在面试的时候更容易复述;还能帮助到更多同学。

甚至有一些厉害的同学通过记录和分享自己的题解,还没毕业,就已经出版了自己的书籍,年入几十万或者百万!

写题解利人利己,何乐而不为呢?

6、精益求精

当你每次成功解题时,LeetCode 系统会生成一份解题报告,告诉你的程序在时间和空间上击败了多少用户。

虽然答出题目就已经很棒了,但还不够。面试的时候,一些面试官就喜欢给你出题目的变种,或者要求你用更优的方式解出题目。所以,在保证完全理解题目解法的基础上,请不断优化你的代码,找到更多的思路和更优解,直到击败 100% 的用户吧。

我们在工作中,虽然未必会直接和算法打交道,但学习算法对工作的帮助真的很大!

解算法题时,我们要对多种算法分析复杂度,从中选择最优解。而在工作中,也是如此,一个需求有很多种实现方式,经常也要设计几种不同的方案,分析他们的成本、性能等差异,选择其中最好的一种进行实施。

所以,请认真对待每一道算法题目,把它当成一个工程问题来解决,相信你的思维会逐渐打开,并逐渐掌握编写高性能程序的技巧。

7、多实践

参加竞赛

我建议大家多参加算法竞赛,这里的竞赛不是指 ACM 区域赛那种大神级别的,别忘了此时我们的目标只是找工作。

其实,LeetCode 网站每周都会开展一次线上算法竞赛,看看谁能在有限时间内最快最多地解题。

在竞赛的过程中,紧张刺激的环境会使我们的精神保持高度集中,能够激发出我们的思维,从而在有限的时间内进行更多的思考,也能帮助我们适应面试的节奏。多多参加还有机会获得他们官方提供的奖励!

此外,参加蓝桥杯竞赛也是不错的,我自己也参加了两届,题目的难度和找工作要求的算法题目难度相当,也能发现自身的不足、激励自己进步吧。

考取证书

这几年,PAT 计算机程序设计能力考试在逐渐升温,分为顶级、甲级、乙级三个级别。

我亲身参与过甲级和乙级的考试,难度适中,虽然目前这个证书的含金量不高,但在备战考证的过程中,你有一个学习的目标,会更有动力坚持下去。在我看来,过程大于结果。

网址:https://www.patest.cn/


加油小伙伴们!