弁言
教程资源
- ZJU 数据结构
- ZJU Advanced Data Structures and Algorithm Analysis
- UCB CS61B: Data Structures and Algorithms
- Coursera: Algorithms I & II
- MIT 6.006: Introduction to Algorithms
- MIT 6.046: Design and Analysis of Algorithms
- UCB CS170: Efficient Algorithms and Intractable Problems
Leetcode刷题指南
代码随想录
很多刚开始刷题的同学都有一个困惑:面对leetcode上近两千道题目,从何刷起。
大家平时刷题感觉效率低,浪费的时间主要在三点:
- 找题
- 找到了不应该现阶段做的题
- 没有全套的优质题解可以参考
其实我之前在知乎上回答过这个问题,回答内容大概是按照如下类型来刷数组-> 链表-> 哈希表->字符串->栈与队列->树->回溯->贪心->动态规划->图论->高级数据结构,再从简单刷起,做了几个类型题目之后,再慢慢做中等题目、困难题目。
即使有这样一个整体规划,对于一位初学者甚至算法老手寻找合适自己的题目也是很困难,时间成本很高,而且题目还不一定就是经典题目。
对于刷题,我们都是想用最短的时间按照循序渐进的难度顺序把经典题目都做一遍,这样效率才是最高的!
而且一个正确的刷题顺序对算法学习是非常重要的!
所以我整理了leetcode刷题攻略:一个超级详细的刷题顺序,每道题目都是我精心筛选,都是经典题目高频面试题,大家只要按照这个顺序刷就可以了,你没看错,左面的菜单栏就是刷题顺序,每一个专题,挨个刷就可以,不用自己再去题海里选题了!
而且每道题目我都写了的详细题解(图文并茂,难点配有视频),我的题解已经陪伴了几万录友渡过了算法学习旅程,质量是有目共睹的。
那么现在我把刷题顺序都整理出来,是为了帮助更多的学习算法的同学少走弯路!
如果你在刷leetcode,强烈建议先按照本站的题目顺序来刷,刷完了你会发现对整个知识体系有一个质的飞跃,不用在题海茫然的寻找方向。
吴师兄学算法
大家好,我是吴师兄。
1、LeetCode 题目太多,全部刷完肯定不是最好最有效的方式,其中涉及到的基本知识点来来回回就那些,同时有非常多的类似题,所以刷经典题,掌握这些经典题是最有效的学习方式。
2、从算法训练营第一期开始到现在的第十二期,吴师兄整理和迭代了非常多的刷题顺序,经过这两年的同学们的反馈,终于整理出一份我认为是最适合新手小白转码同学的 LeetCode 刷题顺序。
3、本刷题顺序涵盖了 205 道算法题,如果你的自学能力强,每天能够投入 2 小时的刷题时间,两个月左右是可以做到完完整整的全部刷完。
4、所有题目均来源于算法训练营的内容,以动画和视频的形式讲解,弱化了文字讲解部分,所以很多题目没有提供题目解析部分,而是以代码注释的形式进行讲解。
5、每道题目的文字解析部分会逐步补充好,为后续实体书的出版提供物料。
6、添加吴师兄的微信 algomooc555 ,后期将会在朋友圈赠送 205 道题目的 PDF 版题解。
如何高效学习数据结构与算法
原作者:三钻
前言
本文是个人基于覃超老师的《算法训练营》的学习笔记,此笔记的内容都是学习后的个人记录、个人总结、理解和思想。仅供参考学习。
很多同学在大学的时候会觉得数据结构与算法很枯燥,很多小伙伴都不愿意听这门课程。甚至以前还觉得能开发一个项目就能成为一个合格的程序员。但是学会算法,或者接触过数据结构与算法后,发现懂这门知识的程序员编写出来的代码相对有更高的质量。代码的性能、写法、底层逻辑和解决问题的能力都会高于不懂数据结构与算法的程序员。
到了如今,如果想成为一个高级开发工程师或者进入大厂,不论岗位是前端、后端还是AI,算法都是重中之重。也无论我们需要进入的公司的岗位是否最后是做算法工程师,前提面试就需要考算法。所以小时不学算法,长大掉头发。
这系列的《算法学习笔记》,与大家一起重温或者学习数据结构与算法。
这里也赠送大家一句话: "好记性不如烂笔头,好记性更不如好笔记"
愿大家在技术银河中终身漂泊学习时,习惯编写自己的笔记,以后这些笔记必定成为我们最珍贵的宝藏!✨
如何系统化学习算法
深入到精通一门知识的我们都需要一个系统化的学习方法,如果这门知识越是有难度,前期就越是枯燥无味,或者甚至觉得很困难。所以学习算法也是一样的:
-
枯燥无味
- 所以需要系统化学习;
- 小步快跑的方式进行学习;
- 不懂就找答案不要埋头苦学;
-
不牢固
- 越是庞大的知识,越学就会越觉得之前学到的知识忘的差不多了;
- 其实就是缺乏知识的稳固性;
-
预习
- 学习任何一门知识,都要先了解和预习这门知识;
- 同理,在学习一门新的开发语言时,我们都会先来一个
hello world
;
-
坚持leetcode刷题
- 要学会算法,并且稳固这一门知识,不断的刻意练习是重中之重;
系统化的效果
系统化学习和拿起一本书最终的效果是不一样的。很多时候我们开始学习一门知识,我们都会看:《xxx深入浅出》、《xxx指南》和《从0到1学会xxx》,其实里面的知识是很庞大的。只靠知识是无法支撑我们的实战和经验的,所以我们需要系统化的学习方法最终达到的目标也是不一样的,例如:
- 提升到职业顶尖水平
- 通过一线互联网大厂的面试
- 要有Leetcode 300+ 刷题量
推荐阅读《Outliner》这本书中的学习方法
精通一个领域
前面说到,任何一个领域的知识都是很庞大的。而且只靠看书,看文章学习都是不够的。所以一套好的学习方法,可以为我们打开一扇大门。而且在打开这扇大门的同时不会因为艰苦、困难、煎熬或者是枯燥而最后放弃。
- 切碎知识点 Chunk it up
- 庖丁解牛
- 脉络相连 - 从根部开始学习,到分支,再到树叶。让每一个知识点都有关联关系
- 刻意练习 Deliberate Practicing
- 反馈 Feedback
数据结构有什么?
-
一维:
-
基础: 数组 array (string),链表 linked list
-
高级:栈 stack,队列 queue, 双端队列 duque,集合 set,映射 map (hash or map),等等
-
二维:
-
基础:树 tree, 图 graph
-
高级:二叉搜索树 binary search tree(红黑树 red-black tree, AVL),堆 heap,并查集 disjoint set,字典树 Trie
-
特殊:
-
位运算 Bitwise,步隆过滤器 BloomFilter
-
LRU Cache (缓存)
参考:覃超老师的《数据库脑图》
算法有什么?
任何的高级算法与数据结构都会转换成If Else,for循环,其实也是最朴素的计算机的知识,没有什么AI,人工智能的知识。高级算法重点是找到重复单元。
- 跳转语句 (Branch) :If-else,switch
- 循环 (Iteration) :for, which,while loop
- 递归 (Recursion) : Divide & Conquer, Backtrace
- 搜索 (Search) :深度优先搜索 Depth first search,广度优先搜索 Breadth first search,启发式搜索 A*
- 动态规划 (Dynamic Programming)
- 二分查找 (Binary Search)
- 贪心 (Greedy)
- 数学 (Math),几何 (Geometry)
参考:覃超老师的《算法脑图》
刻意练习 - Deliberate practice
无论是科学家、国家运动员、技术专家还是游戏职业选手,他们的优秀的背后都有一个共同点:刻意练习。
什么是刻意练习?
- 刻意练习 - 过遍数,持续多边形的练习,用数遍达到质变!(五毒神掌);
- 练习不擅长的地方;
- 如果感到不舒服、不爽、枯燥的话,那证明我们正在爬坡,正在提升!
反馈 - Feedback
很多时候在学习中,特别是在自学的过程,我们永远不知道自己的学习的成果是怎么样的。或者我们有时候会遇到难点但是无法突破,甚至有时候我们以为自己很努力,或者已经很强了。但是其实还只是坐井观天而已。所以我们在学习的时候需要反馈
。所谓的反馈有几种:
- 即时反馈
- 学会使用一门语言;
- 能写出能执行的代码;
- 能写出一个项目;
- 能实现一个功能;
- 主动型反馈
- 高手代码(Github、LeetCode);
- 第一视角止步(看视频,看高手写的代码,学习思路);
- 被动式反馈(高手指点)
- 代码审查 code review;
- 例如:教练看你打,给你反馈;
切题四件套
我个人认为也可以叫解题四大法则
:
-
理解题目(Clarification)
- 在LeetCode看题后,先思考,认真确认和理解题目;
- 避免忽略了一些条件或者是误解题目;
- 面试的时候更加应该跟面试官确认清楚题目、条件、场景等;
-
多种解题方案(Possible solutions)
- 对比时间和空间复杂度 compare (time/space)
- 最优解 optimal (加强)
-
多编写(Coding)
- 代码反复练习和编写;
- 每一种解法都反复练习和编写;
-
多测试案例(Test cases)
- 在LeetCode上可以改变测试案例;
- 多测试几种案例,确保自己的代码可以适应各种特殊情况;
刷题方式(五毒神掌)
第一遍
- 5分钟:读题 + 思考;
- 5分钟过后,没有思路就直接看解法;
- 记录多个解题方法,比较解题方法的优弊;
- 尝试默写代码,训练刻意手写代码;
第二遍
- 自己编写,这时候就不要再看题解了;
- LeetCode提交代码,确保能通过;
- 有Bug没有关系,重复debug到通过为止;
- 编写出多种解题方法;
- 持续优化 - 重点是
执行时间
(可参考LeetCode中打败了多少的人,也可以点击比较优秀的人,学习更好的写法);
第三遍
- 过了一天后,再重复做题;
- 根据自己不熟悉的题目与程度做专项练习;
- 专项练习就是针对自己不熟悉的种类的题,从而刻意练习哪一种题;
第四遍
- 过了一周后,再反复练习;
第五遍
- 面试前,提前2-3周开始重复练习;
总结
这篇笔记中,我们记录了一下关键知识重点点:
-
如何深入学习一门知识
- 通过系统化学习一门知识;
- 最高效和持续的学习算法就是通过系统化的学习;
- 这里推荐大家,真的想学好一个技术,最好的方法就是找对老师,找对课程,找对人;
-
如何攻破庞大的知识体系变成编程职业高手
- 切碎知识点与建立脉络
- 刻意练习
- 反馈
-
数据结构中有什么? - 看脑图
-
算法中有什么?- 看脑图
-
算法练习方法
- 切题四件套
- 五毒神掌