一道题做半天,另外半天看这道题的题解,一台电脑一包烟,一道题解整一天,是我智商有问题吗?
刷了两年题之后,我可以负责任跟你说,刷题吃力很正常,学算法,刷 leetcode 不是一朝一夕的事情,需要一个过程。
而且新手学算法,还很容易陷入一些误区,例如一上来就 抱着《算法导论》这种天书,啥数据结构还没学,就去刷 leetcode,这其实不好,只会让自己放弃算法。
学习算法,应该要一步一步来,要有规划,下面给大家分享下我的算法学习经验吧,觉得有帮助给我点个赞就行了。
一、刷题前的一些准备
如果你连最基本的数据结构,例如链表,队列,栈,二叉树都没有接触过,那么我是不建议你去 leetcode 刷题的,所以我上面先说了先入门一下数据结构与算法,当你学习了这些基础的数据结构之后,其实已经具备了刷题的能力了。
一、基础数据结构与算法知识
1、时间复杂度
2、空间复杂度
一般最先接触的就是时间复杂度和空间复杂度的学习了,这两个概念以及如何计算,是必须学的,也是必须最先学的,主要有最大复杂度、平均复杂度等,直接通过博客搜索学习即可。
3、线性表
- 列表(必学)
- 链表(必学)
- 跳跃表(知道原理,应用,最后自己实现一遍)
- 并查集(建议结合刷题学习)
不用说,链表、列表必须,不过重点是链表。
4、栈与队列
- 栈(必学)
- 队列(必学)
- 优先队列、堆(必学)
- 多级反馈队列(原理与应用)
4、树
- 二叉树:各种遍历(递归与非递归)(必学)
- 哈夫曼树与编码(原理与应用)
- AVL树(必学)
- B 树与 B+ 树(原理与应用)
- 前缀树(原理与应用)
- 红黑树(原理与应用)
- 线段树(原理与应用)
树相关是知识还是挺多的,建议看书,可以看《算法第四版》
不过刷题前也不需要准备这么多,先把最基本的二叉树学了就可以了
书籍推荐看这里:
帅地推荐:少走弯路,各类技术书籍安利
视频推荐看这里:
直通BAT算法精讲视频无套路下载
二、常见算法思想
Leetcode 刷题我还是希望你能在学习一些
算法思想
,一般就这几种
1、递归
2、枚举
3、贪心
4、回溯
5、动态规划
但是,其中最重要的,我觉得就是
递归
,其他的几种算法,也都会有
递归的影子
,并且我刚才说图相关算法、二叉树的遍历等,也都包含递归的使用。
所以,在你刷题之前,或者在学习二叉树、图相关算法遇到递归的时候,我希望你能静下心来,去学一学递归,我也会告诉你,
对于初学者,递归很难
,我是被无数次折腾,无数次看答案
似懂非懂
之后,才突然醒悟了。
你不需要把它学的很精通,但是你要懂一些基本的递归题,知道递归是怎么一回事,例如最简单的
斐波那契数列
得会用递归做吧?
阶乘
也会吧(虽然不是最优解)。
所以,死磕入门数据结构,可以学习下一些算法思想,而
递归
,你必须得入门,至于动态规划、回溯,我觉得慢点学也没有,可以后面刷题遇到时在学,而枚举、贪心,相对比较简单。
这里推荐一份字节大佬的刷题笔记,把各种算法模版都总结好了,跟着学就行:
二、如何刷题
终于,到了刷题这一部分了,如果要说学算法的捷径,那么
刷题便是最好的捷径
,如果你刷的题很少,达不到一定的量,那么再多的捷径,估计也没啥用,只有在满足一定题量的情况下,才适合来谈论所谓的
技巧
。
1、先说一说互联网算法笔试
不过在刷题之前我想先说一说
笔试
,如果笔试不考算法,面试也不考算法,那么我可能在学习算法的这条路上,会少了很多的积极性,你可能会觉得我很功利,但是我觉得,带着功利性的目的去学习算法,也是完全没问题的。
在校招的笔试中,其实这些笔试题还是挺难的,你在 leectode 可以做出 hard 级别的题,但在笔试中,可能连 medium 级别的都做不出,因为笔试的题,都比较灵活,基本都会通过实际的例子来引出一道题,你可能不知道要使用哪种方法来做比较好,有些还是多种方法的结合。
对于笔试的题型,我之前也总结过,无非是以下几种
(1)、基本数据结构的考察:这类题我觉得是比较简单的,主要考场基本数据结构的操作,例如二叉树的层序遍历,链表的逆序等,当然,它不会直接告诉你,让你来逆序或者遍历。
(2)、某种算法思想的掌握:这类题你掌握了某种算法思想,就会比较容易,如果不懂,那就凉凉了。例如动态规划、回溯、枚举、深度/广度、贪心、二分等。其中,我觉得动态规划考的挺多,还要就是 回溯+深度/广度。
(3)、边界条件的考察:这类型的题,估计你一看就有思路,知道该怎么做,但是,它的边界条件特别多,需要分很多种情况来讨论,特别容易出错,有时候会让人陷进去,越做越复杂,这类题主要考场你的思维严谨程度。
(4)、找规律、数学公式:这类型的题,主要是根据数据之间的一些关系,来找一些规律,进而推出他们的通用公式,就像我们高中时,找数列的同项一样。
2、按分类刷题
上面我列了笔试的题型,并且跟你说了笔试是真的挺难的,那么对于我个算法小白来说,该如何做好呢?
我的建议是,
分类刷题,阶段性总结
。例如最开始可以在 LintCode 按照链表/二叉树/递归等这些标签来刷,因为这样可以让你深入掌握每一种方法。
当然,笔试的题之所以难,是因为我们往往不知道用哪一种方法做好,或者说具体属于哪一种题型,那么还有必要分类刷题吗?
答是有必要的,只有当你熟悉每一种题型,你才能灵活使用他们,进而解决各类复杂的题,这就如同你在练功夫的时候,前期你需要把每个招式都打扎实了,之后才能灵活把各个招式连接起来,融合贯通。刷题也是一样,前期先分类,把每个题型掌握起来,后期咱们再随机练习,慢慢着就能灵活应用了。
不过,每次刷了一部分题型之后,我觉得还有必要做一些总结,或者说总结一些
刷题模版
,例如对于二分法查找,其实好几种题型总结起来,就是
开闭区间
的组合,你可以把他们总结起来,例如什么时候用开区间,什么时候用闭区间。
有人可能会说,模版是死的,真的有必要总结吗?
我觉得
有必要总结,但没必要死记
,总结,
只是加深你的理解
,当然,如果你在做题的时候,刚好记住了自己的模版,可以直接套上去,那肯定更好。但是,就算忘了也没事,通过自己的总结,你其实是知道怎么做的了,只是还需要你多花一点时间,快速模拟讨论下各种情况,一样能够做出来的。
也就是说,最开始刷题的时候,可以分类刷题,并且阶段性总结,如果你是初学者,可以先从简单的题做起,例如我刚才说的,简单的递归题,之后一些二叉树、链表的题,因为你可能刚刚学习数据结构不久,刚好可以加深你的理解。
这里推荐一份左神的视频:
牛客网算法第四期
三、刷题时的一些注意点
当我们在做一道题的时候,可能会遇到两种情况,一种是这道题,特么秒杀,一眼就懂思路;一种是,一脸蒙蔽,太难了吧。
一眼就懂思路,有必要做吗?
我的答案是,有必要做。千万不要眼高手低,看着简单,做起来不一定简单,AC 之后,你还要去讨论区看看大佬们是怎么做的,因为有些人的代码,真的写的很简洁,看着就很舒服,咱们可以多学一学的,当然,也有可能那个人就是你自己。
代码写多了,有时候,你就会发现自己真的变强了,写起代码来,bug 也越来越少了,分分钟 AC 一道题。
尽量最优解
其实对于很多题,如果不看时间复杂度和空间复杂度,单单只是 AC,那还是很容易的,但是一提交,你的代码可能只打败了百分之几的人,显然我们是不能满足于这种代码的。
当你做一道题时,一开始可以先暴力做,但后面,还得想想该如何优化,想不出也没事,可以讨论区找空间/时间复杂度更低的代码,或者直接搜索引擎搜索,一般都能搜到别人的代码。
之后跟着别人的代码,自己再实现一波,尽可能把最优解的代码实现起来。千万不要为了 AC 而 AC,不是 AC 的越多就越强的,当你入门之后,更多的是要总结方法,寻找高效率的代码。
这里推荐一份大佬的刷题笔记,总结了 leetcode 上的题解,每道题的题解都是
beat100%
,非常值得大家学习:
清华学霸的刷题笔记(leetcode最优解)
四、总结
说到算法的学习方式,对我来说,真的没有什么捷径之类的,就是像我上面说的,先找本书死磕入门数据结构,就跟着书的例子,把例子跑起来就好了,跑起来也不是一件简单的事情。之后就去接触下一些算法思想,后面就可以分类刷题了,刷题就是最好的捷径了。
当然,不要 AC 之后就完事了,应该尽可能寻找最优解,当你积累了一定的题量,那么你真的会发现自己变强了,突然感觉递归也就那么一回事。
我学习算法时,基本看书 + 网上刷题,也很少看视频,因为我觉得看视频比较花时间,不过我之前在班里还是看到部分人喜欢看视频的,至于看书好还是看视频好,这个看个人喜好吧,也没有说哪种就一定更好。
书籍推荐:《数据结构与算法分析:c语言描述版》、《算法第四版》、《啊哈算法》。
具体可以看这里:
帅地推荐:少走弯路,各类技术书籍安利
最后,大家加油!
作者简洁
作者:大家好,我是帅地,从大学、自学一路走来,深知
算法
,
计算机基础知识
的重要性,公众号「
帅地玩编程
」10万粉丝作者,专业于写这些底层知识,提升我们的内功,帅地期待你的关注,和我一起学习,点击
了解我四年大学学 习之路
转载说明
:未获得授权,禁止转载