六千字干货文:到底要怎么去学算法?五分钟学算法

举个最经典的例子,也是我经常举的例子,背英语单词(在这里我们先不聊背英语单词是不是好的英语学习方法,我们只看如果我们想要背英语单词的话,应该怎么背)。

我发现很多同学拿着红宝书,第一个list都没翻过去就放弃了。这是因为每天背完第一个list以后,第二天会发现:第一个list还是有很多单词没掌握,然后就继续背第一个list。然后一周后,发现自己第一个list都搞不定,觉得英语好难,彻底放弃了。这就是“完美主义”:不把第一个list“彻底”掌握不肯继续前进。这样是不对的。背了一个list,能多记一个词,都是进步。就算一个词都没记住,模糊有了印象,也是一种进步。

我们不应该过度着眼于我们还不够完美。

学习不是要么0分,要么100分的。80分是收获;60分是收获;20分也是收获。有收获最重要。但是因为着眼于自己的不完美,最终放弃了,那就是彻底的0分了。

仔细想,这种“完美主义害死人”的例子特别多。我看到过很多同学,其实是在学习的路上,被自己的“完美主义”逼得“放弃了”——由于学习中有一点没有做好,遭受到了一点点挫折,最终就放弃了整个学习计划。每个人都一定要接受自己的不完美。想开一点:我们都不是小升初考了满分,才能上初中的;也不是中考考了满分,才能读高中的;更不是高考考了满分,才能念大学的;将来也不会是大学所有科目都是满分,才能出来工作。不完美其实是常态,根本不会影响我们学习更多更深入的内容。但是在自学过程中,很多同学却要求自己在自己制定的每一步计划中都达到“完美”,才进行下一步。最终结果,通常都是“放弃”:(

可能有的同学会跳出来反驳我:学习当然要认真啊!在这里,我必须强调,我所说的“不要完美主义”,和“学习认真”是不冲突的。

什么是“完美主义”,什么又是“囫囵吞枣”,这是一个“度”,每个人其实不一样。不要“完美主义”,不代表学习可以草率前行。

每个人都必须要找到适合自己的学习节奏。我的经验是:在一些情况下,问自己一句:是不是自己又犯“完美主义”的毛病了:)

什么意思?就是现在信息太发达了,对于大多数领域的知识,网上会有很多所谓的“学习路径”。我不是说这些学习路径没有用,但是不能“过度”依赖这些所谓的学习路径。

比如,很多同学想学机器学习,大多数学习路径都会告诉你,机器学习需要数学基础。于是,很多同学就转而学习数学去了,非要先把数学学好再去学机器学习。可是发现数学怎么也学不好(在这里,可能完美主义的毛病又犯了),而机器学习却一点儿都没学。最终放弃了机器学习,非常可惜。

其实,如果真正去接触机器学习,就会发现,至少在入门阶段,机器学习对数学的要求没有那么高。正因为如此,我一直建议:只要你在本科接触过高数,线数,概率这些科目的基础概念,想学机器学习,就去直接学习机器学习。学习过程中发现自己的数学不够用,再回头补数学。在这种情况下,数学学习得也更有目标性,其实效果更好。

类似这样的例子还有很多,很多同学想学习做iOSapp,就先去精通Swift语言,或者想做androidapp,就先去精通java语言。在我看来大可不必。以我的经验,只要你有一门编译型语言基础,大概看一下这些语言的基础语法,就可以直接上手iOS或者androidapp的开发了。先能做出一个最基本的app,在这个过程中,就会意识到语言特性的意义,再回头深入研究语言也不迟。此时还能结合真实的开发任务去理解语言特性,比没有上手app开发,抽象地理解语言特性,有意义的多。

虽然我一再强调对预算法的学习,语言不重要,但还是有很多同学表示,要先把C++学透,再回来把课程中的算法学好。这是完全没必要的。事实上,在我的这两门课程中,我看到的收获最大的同学,是那些能够把课程中的算法思想理解清楚,然后用自己熟悉的语言去实现的同学:)

依然是:不要“过度”学习路径依赖,什么叫“过度”,每个人的标准不一样。每个人都需要寻找自己的那个“度”。

不是说权威教材不好,而是每一本教材都有其预设的读者群,如果你不在这个预设的读者群的范畴里,教材再好也没用。最简单的例子:再好的高数教材,对于小学生来说,都是一堆废纸。

我经常举的一个例子是《算法导论》。我个人建议如果你是研究生或者博士生,已经有了一定的算法底子,才应该去阅读《算法导论》,我在我的课程的问答区,也谈过如何学习使用算法导论。

但是对大多数本科同学,尤其是第一次接触算法的同学,《算法导论》实在不是一个好的教材。

但很可惜,很多同学在学习中有上面的两个毛病,既过度路径依赖,别人说《算法导论》好,学习算法要走学《算法导论》这个路径,自己就不探索其他更适合自己的学习路径了,一头扎进《算法导论》里;同时还“完美主义”,对于《算法导论》的前几章,学习的事无巨细,但其实接触了很多在初学算法时没必要学习的内容。最后终于觉得自己学不下去了,放弃了对“算法”整个学科的学习。认为算法太难了。

诚然,算法不容易,但是,一上来就抱着《算法导论》啃,实在是选择了一条完全没必要的,更难的,甚至可能是根本走不通的路。对于一个领域的学习,了解市面上有什么好的教材是必要的,单也不能迷信权威教材。每个人必须要去探索学习如何寻找适合自己的学习材料。

很多同学问我最初学习算法的是什么教材,我告诉他们是这本教材:《算法设计与分析基础》。在这里,我完全没有推荐这本教材的意思。事实上,现在我有点儿“鄙视”这本教材。因为我在学习它的过程中,发现这本教材有很多错误(帮助它纠正错误其实也提高了我的水平:)

当然,现在这本书的版本可能也和我当时学习的版本不同了,大部分错误应该已经纠正了。)但它确实是我的一本很重要的算法启蒙教材。

关键原因是,它够薄。

在大多数时候,如果有人问我教材推荐,基本上我的回答都是,如果是入门水平:随便找一本在京东,亚马逊,豆瓣上,评分不太差的“薄”的教材,就ok了。

在这里,关键字是够“薄”。

因为“薄”的教材能让你以最快的速度看完,对整个学科有一个全盘的认识:这个领域是做什么的?解决什么问题了?整体解决问题的思路是怎样?解决问题的方法大致是怎样划分的?一些最基础的方法具体是怎样的。这些在初学阶段是至关重要!是让你全盘把握整个领域脉络的。

虽然通过这么一本薄薄的教材,你的脉络把握肯定不够全面细致,但比没有强太多!我看过不少同学,一上来学习《算法导论》,关于复杂度分析的笔记做了好几页,然后就放弃了,可是连什么是动态规划都不知道。这样完全没有对“算法”这个领域有全面的认识,甚至可以说根本没有学过“算法”!

先用薄教材入门,再找“厚”教材,细细体会其中的细节,是我百试不爽的学习方法。

另外,在这里,我还要强调“入门教材”,很多教材虽然够“薄”,但不是“入门教材”。大家要注意。

很多同学理解了要找“薄”教材入门的道理,却还是非要我推荐一本具体的“薄”教材,说实话,很多时候这让我有点儿哭笑不得。

因为我随便推荐一本,我确实不敢保证它是“最好的”,“最适合你的”,但是各个领域那么多教材,我又不可能都一一看过,一一比较过。

最最重要的是,我的学习经验告诉我,在大多数情况下,学习不是一本固定教材可以搞定的。

非要找到一本“最适合自己的”教材,然后就一头扎进去,其实是不科学的。我印象很深刻,我读本科的时候,那会儿申请了一个项目,要做一个网站(那时候服务端都用ASP.NET),我一口气从图书馆借了10本ASP.NET的教材,然后以一本最薄的书为主干去看,发现这本书介绍不清楚的概念,马上就从其他书里找答案。

但是,大多数同学喜欢仅仅扎进一本书里,一旦选定了自己的学习材料,就对其他材料充耳不闻,甚至是排斥的心理。这种做法,一方面又是“完美主义”的表现——非要把这本教材学透;另一方面,其实也是“犯懒”的表现,不愿意多翻翻,多看看,自己多比较比较,自己去寻找最适合自己的材料,一味地盲目相信所谓“大神”的推荐,殊不知,这些推荐,不一定是更适合自己的材料;更何况,还有很多大神,明明是靠不出名的“薄”教材入的门,但给别人做推荐的时候,就突然变成自己是算法奇才,自幼阅读《算法导论》而所成的神话了:)

对于计算机领域的学习来说,真正动手实践去编程是异常重要的。怎么夸大其中的作用都不过分。

这就好比学游泳,必须下水去游泳;或者学开车,必须亲自上路。

否则你说的再头头是道,一个小学生文化水平的人,只要他开过车,游过泳,都能在这两个领域瞬间秒杀你。

很多同学都说我的算法讲得好,其实,我一直认为,这其中的一个最简单的秘诀就是:我带领大家把大多数算法都非常细致的实现了一遍;或者对其中的应用进行了非常具体的实践。

反观大多数高校教育,对于算法或者机器学习这种一定程度偏理论的学习,通常非常不强调实践。最终的结果是学习者只是接受了很多抽象的概念,但对其中具体的实现细节,却是云里雾里。

我见过太多同学,都明白什么是O(n^2)复杂度,什么是O(nlogn)的复杂度,却问我对于100万的数据规模,为什么自己的选择排序运行起来就没反应了。答案很简单:O(n^2)的复杂度太慢了,100万的数据规模太大了,一般家用计算机转选择排序一时半会儿是转不完的。这些同学一定理解O(n^2)的算法比O(nlogn)的算法慢,却没有真正实践过,不知道这个差距到底是多少。

在我的课程中,经常遇到有些同学提出这样的问题:这个算法的某句话(或者某段逻辑),为什么要写成A的样子,而不是B的样子?这种问题其实很好,但我觉得解决方法也很简单,实际的去把算法改写成B的样子,实际的运行试试看,看会发生什么。如果发生了错误,仔细分析一下,为什么会有错误?如果没有错误,具体比较一下:A和B两种不同的写法,为什么都正确?又有什么区别?

真正的学习上的提高,就发生在这个过程中。

我当然可以告诉给同学们一个结果,但是自己亲自实践一遍,相比阅读我给出的一个答案,自己对其中问题理解的深刻程度,是完全不可比拟的。

我看到的另一类“经典”问题就是:老师,这个代码为什么错了,然后贴一大段代码。这种问题背后,依然是,透露着学习方法的不对劲:提问的同学懒得debug。

在计算机领域,debug近乎和实践是一个意思。如果只是把材料上的代码“抄”一遍,这不叫实践,这叫抄代码。小学生也能做。但是“抄”一遍,不小心没抄对,发生了错误,然后自己一点一点调试,找到错误的根源,这叫真的实践。小学生不能做。(当然,我更推崇的是:自己理解了算法的逻辑,按照自己的理解,把算法写出来:)

debug不仅仅是找到代码错误,解决错误的手段,其实更是一个重要的学习手段。通过debug,看看自己写的程序执行逻辑,哪里和自己设想的不一致?再回头看自己哪里想错了,或者想漏了,分析一下自己为什么想错了,或者想漏了,等等等等,依然是,进步就是发生在这个过程的。

还有很多同学,对于算法的一些问题,会问:老师,你是怎么想到用这样的方法的?对于这类问题,我的回答一般都是:你见的还不够多。

不知道是不是受高中阶段学习的影响,有一些同学特别执着于就着一个单一的问题,寻找其中的“解题路径”。当然,我不是说这是完全错误的,但也有一个“度”。

仅仅对着一个问题思考,很多时候都是死胡同。你见识的还不够多,就不足以帮助你总结出更加“普遍”的问题解决的规律。当你见得足够多的时候,一切就都变得很自然,所谓的“量变到质变”。

不过,大多数同学在这个环节都会“犯懒”,企图通过一个问题就理解问题的本质,这其实和企图通过一本教材就精通一个领域的想法是一样的,是不现实的,不可能的。同时,这里又包含着学习过程中的“完美主义”的思想,遇到一个问题一定要把它想的无比透彻。但是我的经验告诉我:大多数问题,其实都是需要“回头看”的。随着你对一个领域理解的越深入,回头再去看那些曾经的问题,都会产生新的视角,对于很多曾经想不明白的问题也豁然开朗。这也是“进步”的根源。如果卡在一个问题上不前进,不给自己“回头看”的机会,甚至最后是放弃了,就什么也没有学会了。

所以,很多时候,你发现对一些问题“百思不得其解”,或许不是因为自己“笨”,而是因为“还不够努力”:)

有一天,在我的一个算法课程群里,有个滴滴的后端大神发招聘,结果大家七嘴八舌的就议论开了,大致主题思想就是:自己什么时候能够成为滴滴的后端大神。这位滴滴的后端大神今年32岁;大多数议论的同学,其实连22岁都不到。我告诉他们,其实10年后,你们就是大神。

这其实很好理解,回想十年前,也就是12岁的你,和现在的你比较,是不是天壤之别?如果把你扔到一堆12岁的小朋友中间,22岁的你是不是就是个大神?同理,32岁的人,已经在业界摸爬滚打了那么多年,扔回到22岁的大学生中间,当然是大神:)

THE END
1.算法笔记(三)算法学习技巧从开始学习算法已经有两三个多月的时间了,从简单到深入层次展开,层层优化,对算法的理解也在逐渐加深,不在那么片面,虽然现在还是片面一些,对它的了解也仅仅知道冰山一角,还有很多的内容需要我们去学习去挖掘。 思路 在学习前我们要尽可能快速阅读一遍要学习的书籍,这样不仅仅让我们知道了有哪些内容需要学习,同时也在https://www.code456.com/article/3598351.html
2.从啥也不会的小白,如何成为合格的算法工程师?算法工程师之前有一个小伙伴在留言当中问我,说自己想要从事算法工程师的工作,但是不知道应该从哪里入手,请问我应该怎么办。 这其实是一个老生常谈的话题,也是一个很大的概念。我很难用三言两语告诉你究竟应该如何做,但我可以告诉你一个合格的算法工程师应该至少需要具备什么样的能力,也许可以帮助你们找到前进的方向。 基础 https://aiqicha.baidu.com/qifuknowledge/detail?id=10100085880
3.读者问我怎么学算法,那就来聊点方法论腾讯云开发者社区你看我写的算法套路很通俗易懂,大家喜欢看,那只能代表我这个人的逻辑性很强,并不代表我来聊天大家就喜欢看,学习的时候才需要逻辑,平时又不需要。 不过,今天还是想简单和大家聊聊,因为很多读者问起,想让我讲讲怎么刷题,怎么学好算法,有没有必要去拿个算法竞赛奖之类的。 https://cloud.tencent.com/developer/article/1880928
4.即将到来的算法革命,让孩子学好数学迟早有一天,我们将通过计算解决一切问题。如果投资这件事指的是投资未来,那么从现在开始关注一切和算法相关的事情就并不为过,至少,你可以让孩子在一个新的意义上学好数学。语言是社交的工具,算法则是他和机器打交道的工具。 AI,也就是人工智能,以算法为基础。看一个有趣的报道,法国圣母大学的研究人员最近开发出https://laoyaoba.com/html/share/news/619312?source=app_android_v2
5.《算法与数据结构》精品课:线上线下融合,师生协力共创编程教学新(更多博客推文可关注公众号“SIST算法与数据结构”或访问课程主页https://smart.sist.shanghaitech.edu.cn/cs101/进行查看) 学好这门课的秘诀? 学好一门课程,需要脚踏实地进行学习与反思,没有捷径可走。但是有一些学习建议,可以帮助同学们更好地学习和理解这门课程。 https://sist.shanghaitech.edu.cn/_t335/2023/1205/c2858a1086548/page.htm
6.什么是算法?程序员如何学好算法?怎样才能学好算法并写出优秀的程序程序员如何学好算法? 文章讲述了程序员如何通过学习基础知识、利用刷题平台和参与实际项目来提高算法技能和编程能力。强调了制定学习计划、理论与实践相结合、记录总结和寻求帮助的重要性,并提到了LeetCode等刷题平台和开源项目合作在提升过程中的作用。 摘要由CSDN通过智能技术生成https://blog.csdn.net/huangdi6678/article/details/131334402
7.算法岗还是工程岗?关于职业选择的一点小思考职业发展以机器学习平台研发工程师-Data进行举例,首先你至少要精通或者熟悉一门编程语言(重点,不要贪杯),其次就是数据结构与算法要学好(这里所谓的学好并不是说你在某某平台刷了多少题,更重要的是要了解算法在生活中的应用场景,比如对于栈这种数据结构,大家在学校里可能就只知道栈可以解决括号匹配问题,但你是否知道你在日常https://ac.nowcoder.com/discuss/995242?type=9&order=0&page=1
8.算法分析入门教程实战篇及应用篇要想既快又扎实地学好破解,必须养成一个好习惯。什么,这不是算法分析吗?你怎么竟扯好习惯?没错。要学好算法分析,必须要有一个好习惯。否则事倍功半。学破解的好习惯(也是做CRACK ME 的好习惯): 1.坚持独立完成破解(CRACK ME)。贵在坚持。开始时很吃力,成果也不明显。没关系。万事开头难,坚持。https://www.pediy.com/kssd/pediy10/59537.html
9.代码随想录——跟着Carl学算法先后在腾讯和百度从事技术研发工作多年,对数据结构和算法有深刻理解。CSDN博客专家,各大OJ刷题总计过千题。公众号:代码随想录,目前有8w+垂直程序员粉丝。 章 准备面试要知己知彼 1.1 面试官为什么要考查算法 1.2 编程语言 1.2.1 学好算法之前更要学好编程语言 1.2.2 代码规范 1.3 如何写简历 1.3.1 简历模板 http://www.96192.com/product/detail/900082
10.把力扣算法题刷熟了就能稳进大厂吗?还得学会这一招才能高枕无忧接下来我们跟随大神的脚步,一步一步学会算法分析。 Part.3 算法分析这样学,进大厂就稳了 要学好算法分析,还需要预备一些基础知识,首先是数学基础,包括离散数学、实分析和组合数学;然后要有一定的编程经验,掌握一门编程语言,了解基本数据https://mp.weixin.qq.com/s?__biz=MzA3NTIzMzIxNQ==&mid=2652925686&idx=1&sn=7a776c9f4adfb9f462932f0f1e8b8696&chksm=855fdd51414e0204d71c18234ec73586d54b9499e4c5cb6b35d02ff2dbbedd990ee1025a077d&scene=27
11.算法系列15天速成——第十五天图下(大结局)相关技巧边代表两个城市之间的距离,当有n个城市时,可能会有n(n-1)/2条边,那么怎么选择(n-1)条边来使城市之间的总距离最小,其实它的抽象模型就是求“最小生成树”的问题。3. prim算法当然如何求“最小生成树”问题,前人都已经给我们总结好了,我们只要照葫芦画瓢就是了,https://www.jb51.net/article/43301.htm
12.labuladong的算法小抄(豆瓣)《labuladong的算法小抄》专攻算法刷题,训练算法思维,应对算法笔试。注重用套路和框架思维解决问题,以不变应万变。 第1章列举了几个最常见的算法类型及对应的解题框架思路,包括动态规划、回溯、广度优先搜索及双指针、滑动窗口等算法技巧。 第2章用动态规划的通用思路框架解决了十几道经典的动态规划问题,例如,正则表https://book.douban.com/subject/35252621/
13.算法太难学了!说到这里,又有人说了,算法太难学了,哪怕在 Leetcode 上刷题,也很难坚持。 我只能说,算法学习也是有方法的,如果想要学好,必须要掌握正确的学习方法,建立自己的算法知识体系。这里推荐给大家前 Facebook 工程师覃超和极客时间联合开设的《算法训练营》。 https://www.zhuanzhi.ai/document/0218b4cf43498c210058bdadd828a03a
14.算法到底应该怎么学?优秀的小伙伴都知道,学好算法与数据结构,不单单是为了应付技术面试的需要,更重要是提升自身编程水平。https://www.zhihu.com/question/25693637/answer/516725253
15.算法简单学习(一)——前言将数据结构和算法比作计算机的基石毫不为过,追求程序的高效是每一个软件工程师的梦想。下面就是我对算法方面的基础知识理论与实践的总结。 算法是干什么的 当我们编写程序时,一般是实现一种先前设计好的、用来解决问题的方法。这种方法一般与使用的计算机无关,可能对多种计算机和多种语言同样适用,计算机里面算法(algorhttps://www.jianshu.com/p/f74f4ef33e93
16.编程竞赛宝典C++语言和算法入门首先,算法(Algorithm)一词源于算术(Algorism),具体地说,算法是一个由已知推求未知的运算过程。后来,人们把它推广到一般过程,即把进行某一工作的方法和步骤称为算法。一个程序要完成一个任务,其背后大多会涉及算法的实现,算法的优劣直接决定了程序的优劣。因此,算法是程序的“灵魂”。学好了算法,就能够设计出更加优异https://www.epubit.com/bookDetails?id=UB77a9ce8133887