☰
算法日迹:从零开始记录算法学习的真实成长路径
2026/10/20 4:02:05 网站建设 项目流程

"算法日迹"这个名字,是在一个夜深人静的时候定下来的。那天我刚刚结束一场在线笔试,三个小时三道题,最后只写出了一道半。最让我难受的不是不会做,而是第二题我盯着屏幕看了快四十分钟,题目认识我、我不认识它,脑子里一片空白。关掉浏览器之后我没走,坐在那里想了一个问题:我前前后后也看了不少算法教程、收藏了不少题解,为什么一到自己上手还是不会?也就是在那个晚上,我决定把接下来的算法学习过程完完整整地记录下来,于是有了这个系列。

它不是什么"三十天速成大神"的宝典,也不是"背完这些题就能进大厂"的速效药。它就是一份诚实的算法学习日记:我怎么从零开始重新学、怎么卡壳、怎么从"看答案都懂"到"独立写出来",以及这一路上踩过的坑、总结的方法、调整的心态。如果你也是刚准备认真学算法,或者已经刷了几十道题但心里还是没底,这个系列应该对你有用。我不会只展示顺利的部分,会更真实地展示那些反复想不通、写错、改错、重来的过程——因为那才是大多数人的真实状态。

1. 从一道不会做的题说起:这个系列诞生的起点

1.1 那天晚上的崩溃与反思

具体来说,那次笔试是某家公司投完简历后发来的线上测评。第一题是个偏热身的问题,我很快写出了能通过的版本;第二题是一道跟二叉树有关的题,要求做某个遍历统计,我大概知道要用递归,但写着写着就乱了,递归边界怎么都想不清楚;第三题最惨,题干里的几个术语我都能看懂,但完全没有解题方向,最后只能写个最暴力的循环去碰运气。

提交完的那一刻,我盯着"部分通过"三个字,心情很复杂。你说我完全不懂二叉树吧,我明明知道什么是前序、中序、后序,也看过相关的文章;但你说我会吧,真给我一道没见过的题,我却连从哪里下手都不知道。那天的挫败感,不是"题目难"可以解释的,而是我开始怀疑自己的学习方法出了问题——我好像在学算法,又好像只是在"看"算法。

回家的路上我想起一个很扎心的事实:我收藏夹里的算法教程不下二十个,网盘里还有几个G的视频课,但它们绝大部分都没有被我真正"消化"过。我看视频的时候觉得每道题都能听懂,关上视频之后却很少自己动手写一遍。原来我一直在做的,是用"看过"来欺骗"学过"。

1.2 一位朋友的当头一棒

笔试结束后第三天,我约了一个做开发的朋友吃饭,把这事跟他说了。他听完一点没安慰我,上来就是一句:"你这不叫学算法,叫背题。你回想一下,上一道你看过题解的题,让你现在手写出来,你还写得出来吗?"

我仔细想了想,真的写不出来。

他接着说了一句话,我现在都还记得:"看懂题解是世界上最简单的事,因为那是别人帮你把最难的思考过程做完了。而你要练的偏偏是那个你自己从来没做过的部分——从题目到思路的这一步。你跳过它,直接拿着结论跑,跑一百遍也没用。"

这段话我反复消化了很久。确实,我在做题时经常是这样的流程:打开一道题,读题三分钟,没思路,于是点开题解,然后恍然大悟,觉得自己"会了",接着感慨一句"我怎么没想到",就关了页面。下次遇到同类型的题,依然没思路,再点开题解,再恍然大悟,无限循环。

那天晚上我重新整理了一下自己的问题清单,写下来之后发现三个核心毛病:第一,没有独立做题的耐心,想不出来就想看答案;第二,没有复盘机制,做过等于忘了;第三,没有成体系的专题训练,东一榔头西一棒槌。如果不解决这三个问题,再刷两百道题也还是原来那个我。

1.3 "梦开始的地方"到底是什么意思

很多人听到"梦开始的地方",脑海里浮现的可能是信心满满、整装待发的样子。但对当时的我来说,梦开始的地方其实非常朴素——就是承认自己不会。

我在起"算法日迹"这个标题的时候,特意加了一行副标题:"简介:梦开始的地方(必看)"。这里的"必看"不是说这篇写得有多厉害,而是如果接下来打算跟着这个系列一起走,这一篇相当于我们的出发仪式:从这里开始,我不再假装自己什么都会,不再靠看题解获得虚假的满足感,而是老老实实地从第一道题开始,把每一个知识点都亲手写一遍。

所以这个系列会忠实地记录我在算法这条路上的真实轨迹。可能会经常出现"这道题我想了一个小时还是没做出来"的失败记录,也可能会出现"原来这个问题还有这么妙的解法"的惊喜瞬间。这些都是真实的、值得记录的东西。这篇简介既是写给我的,也是写给准备开始或正在挣扎的你的。

2. 算法对我的意义:不是题库,是底层的思维方式

2.1 算法思维在日常编码中的隐形作用

有相当长一段时间,我以为算法只跟笔试面试有关,平时写业务代码根本用不上。后来发现我错了——算法从不以"做一道题"的形式出现,它是以一种思维方式渗透在代码的每个角落里的。

举个例子。有次我做一个数据导入功能,需要把两个来源的数据合并去重。第一版我用的是最直观的写法:外层循环遍历第一个列表,内层循环检查第二个列表里有没有重复项。功能倒是跑通了,可当数据量从几百条涨到几万条的时候,接口直接慢到超时。我当时脑子里突然闪过"复杂度"这个概念,算了算,两层循环就是O(n²),两万条数据那就是四亿次比较,不卡才怪。

后来我改成先把其中一个列表转成哈希集合,再遍历另一个列表去查重,整体复杂度降到O(n),几毫秒就跑完了。你说这道题难吗?不难。但它让我第一次意识到,算法思维不是让我去背诵某道题的标准答案,而是给了我一个分析问题、估算性能、优化方案的"概念工具箱"。

再比如调接口慢的问题,很多人第一反应是"是不是数据库没加索引",但如果你具备算法思维,你会先顺着代码逻辑看一遍有没有循环里套查询、有没有重复计算、有没有不必要的全量遍历。排序前先想清楚比较规则,搜索前先想清楚数据组织方式,这些习惯都是从算法训练里长出来的。

2.2 从"看答案都懂"到"独立写出来"的学习闭环

我慢慢总结出,学一道算法题有一个完整的学习闭环,大概分四步:

  • 第一步:看懂题解。这是最入门的一步,理解别人的思路和代码。
  • 第二步:跟着题解敲一遍代码。很多人停在这一步就觉得自己会了。
  • 第三步:合上题解,自己在编辑器里从零写出来。卡住的地方就是你需要补的地方。
  • 第四步:隔三到五天,完全不看任何提示,再独立做一遍这道题。这一步能写出来,才说明真正掌握了。

绝大多数人只走到第二步。我自己就是最典型的例子——看题解的时候一切尽在掌握,合上答案之后大脑一片空白。这就好比看别人跑步,看一百遍步频和姿势,自己上跑道还是喘成狗。你看懂了跑步的"道理",但你的肌肉、你的呼吸、你的节奏,全都需要亲自跑出来才能建立。

所以我在这个系列里会反复强调"独立实现"的重要性。一道题即使你看完题解觉得很简单,也请把答案关掉,自己从空文件开始写一遍。写不出来没关系,那恰恰说明你找到了一个值得记录的知识盲区。把盲区暴露出来,再针对性地补上,这样的学习效率远高于一次性看十道题的题解。

2.3 算法训练重塑了我面对问题的态度

这句话听起来可能有点虚,但我自己的体会是真实而具体的:学算法之后,我面对复杂问题时的第一反应变了。

以前写代码遇到一个没做过的东西,第一反应是"好烦、不会、怕搞不定",容易焦虑。现在我会下意识地把它拆成几个小问题,逐个去验证:先确认输入和输出是什么,把大目标拆成几个中间步骤,对每一步选择最简单可行的方法,先跑通再优化。这种"拆解-验证-迭代"的模式,本质上就是算法里分治和迭代思想的日常化。

有次接了一个需求,功能本身不算难,但要考虑多种边界情况,逻辑很绕。换作以前,我会直接在函数里堆各种if-else,改一个bug又带出另一个bug。那次我逼着自己先在纸上画出输入的可能分支,写清楚每种情况下应该走哪个路径,然后再动代码。结果代码反而短了,逻辑也清晰了,一次通过测试。这是算法练习带给我的额外收获——它训练的不只是做题能力,更是一种结构化拆解问题的习惯。

3. 我打算怎么学、怎么记、怎么写

3.1 按专题学,不按序号刷

很多人在题库里刷题是按顺序来的,今天刷到第30题,明天刷到第31题,后天第32题。问题是这些题目之间没有关联,今天接触链表、明天跳到动态规划,知识是碎片的。我决定改变策略:按专题进行学习,每个专题集中突破一到两周,吃透一个知识点再进入下一个。

我给自己规划的学习地图大概是下面这张表,后面也会按这个顺序来更新系列文章:

专题模块核心内容典型场景
数组与字符串遍历、双指针、前缀和、区间操作最基础、最常用的思维模型
链表指针操作、反转、快慢指针、环形判断理解引用的好材料,面试常考
栈与队列单调栈、滑动窗口、括号匹配解决"下一个更大""窗口最值"等问题
哈希表计数、映射、缓存、去重用空间换时间的最经典工具
二叉树前中后序、层序遍历、递归推导递归思维的基石
排序与查找常见排序、二分查找及边界处理边界条件极其考验细节
递归与回溯全排列、组合、子集、搜索路径理解"状态回退"的关键模块
动态规划背包、子序列、区间DP、状态压缩最让人头疼但收益最大的专题
图论入门图的遍历、拓扑排序、最短路进阶内容,后续安排

按照表格里的顺序,一个专题连续做十到十五道题,你就会发现:很多题目看似不同,底层的思考模式是一样的。比如"双指针"这一招,既能处理有序数组的两数之和,也能处理链表找环,还能优化滑动窗口。这种"模式识别"能力,只有在专题化的大量同类练习中才能建立起来。

3.2 我的"一题四步"笔记法

我之前有个坏毛病:做完题从来不记笔记,当时觉得反正做过一遍了,以后需要再看代码就行了。事实是,过了一个月回来看自己的代码,经常完全想不起当时为什么这么写。所以我给自己设计了一个固定的笔记模板,每道题都按这个结构来记,便于日后检索复盘:

记录项说明
题目与来源用自己的话简述题目,不抄原题
我的初始思路看到题后第一反应打算怎么做
卡壳点写代码时在哪个环节卡住了,卡了多久
错误与修正运行时出了什么错,为什么错,怎么改对
最优解对比看了其他人的解法后,自己的思路差在哪个环节
可迁移的结论这道题沉淀出的泛化思路,下次同类题可以用

这个模板看起来有点笨重,记一道题可能要额外花二十分钟,但它才是真正让一道题"长"在脑子里的关键。尤其是"卡壳点"这一项,一定要诚实记录。很多时候你以为自己记住了,其实下次遇到同样的坎还是会卡。把卡壳点写下来,过两周再翻一次,相当于拿着地图重新走一遍当初迷路的地方,会格外有效。

我还会在每周日抽半小时把本周所有笔记里的"可迁移的结论"汇总到一张单独的页面上。这样做的好处是,每个知识点经过了两轮沉淀,已经能内化成自己的一套解题判断逻辑。比如看到"求最值"会先想动态规划,看到"有序数组+查找"会先想二分,看到"连续子数组"会先想前缀和或滑动窗口。

3.3 卡住了怎么办:我的"三十分钟法则"

做过算法题的人都有体会:最大的心理障碍不是题目难,而是"想了很久还做不出来"带来的挫败感。以前我一挫败就想点题解,但点开之后又觉得自己亏了——好像这道题永远不是自己解出来的。为了形成健康的节奏,我给自己定了"三十分钟法则"。

规则很简单:一道题,先独立思考三十分钟。如果三十分钟内完全没有头绪,允许自己看题解,但看之前必须先在笔记里写下"我卡在哪一步"——是因为没有思路,还是不知道用什么数据结构,还是边界处理把握不住。把这个卡壳点写清楚之后,再看题解,你会发现自己更容易理解别人解法的精妙之处,因为你已经知道自己缺的是哪一块拼图。

看完题解之后还有一个强制动作:把题解关掉,自己从零开始重写一遍。这一步不能省。如果重写的时候又卡住了,回到笔记里把卡壳原因再补充一次,这个反复"卡住-解决-再卡住-再解决"的过程,恰恰是记忆最深刻的时刻。

记住一个关键心法:卡壳不是学习失败的标志,而是学习正在发生的标志。一个从不卡壳的人,说明他一直在自己的能力舒适区内,并没有真正学到新东西。遇到卡壳,别急着否定自己,把它当成一个待解决的问题来研究,这种心态的转变很重要。

4. 系列内容规划:接下来的文章会写什么

4.1 基础数据结构笔记:从最常用的几个开始

系列内容会优先覆盖所有算法学习都绕不开的基础数据结构。这部分虽然听起来枯燥,但它们是所有高级算法的地基。

我会按之前那张表格的顺序来推进。举个例子,讲数组时不会只讲"数组就是一段连续内存",而是会用一个真实的算法题做引子,比如"在一个有序数组中找到某个数的插入位置"。这道题看似简单,但能打磨你对二分边界的感觉。链表部分则会重点讲指针操作的细节,因为很多人在反转链表时把指针绕晕,本质上是没有真正理解引用的指向变化。

每一篇数据结构笔记都会采用类似的叙事逻辑:先解释这个结构解决什么问题、有什么性能特点,然后拿一道有代表性的题目走一遍完整的思考过程,最后给出一段可以直接运行的示范代码。读者不需要额外准备什么,只需要跟着文章把代码自己敲一遍,就能获得实实在在的体感。

4.2 高频算法思想专题:双指针、二分、动态规划与回溯

数据结构之外,更重要的一块内容是算法思想。这部分我会把重心放在四个方向上:双指针与滑动窗口、二分查找及其边界处理、递归与回溯、动态规划。

先说二分查找,看起来简单,实际上边界条件极其容易写错。我计划专门用一篇文章来梳理"为什么大家写二分总死循环",并给出一个统一的边界处理模板。动态规划更是很多人心中的坎,我打算把它拆成一个系列,从最基础的斐波那契式递推开始,逐步过渡到背包问题、最长递增子序列、编辑距离等经典模型。每个模型我都会给出"状态定义-转移方程-初始化-遍历顺序"的完整推导,而不是直接甩一个状态转移方程让你背。

回溯部分则会跟递归深度结合,用"画递归树"的方法来帮助理解。这个方法的受益者不只是新手,很多有经验的开发者遇到组合爆炸问题时也会靠画搜索树来理清思路。这些专题文章会比基础数据结构的文章更长、更细致,因为它们承载了算法学习中真正的难点。

4.3 面试复盘与真实题目分析

这个系列不打算只讲"纸上算法",还会做面试题的复盘分析。我会把碰到的有代表性的笔面试题拿出来,用匿名化的方式做完整拆解:从第一眼看到题目的心理活动,到前几分钟的试探性思考,再到逐步收缩思路、最终写码验证的完整过程。

举个我打算写进系列的例子:一道看起来像"找规律"的题,很多人上来就试图用数学公式推导,但我复盘时发现,更稳妥的路径是先暴力枚举小规模数据,把结果列出来找规律,再尝试用递归或动态规划给出稳妥解法。这种"先跑小规模例子、再归纳模式"的思路,其实是算法学习中很实用的一招。

除了思路,我也会分享笔试环境下的时间分配策略,比如先做会做的题、不会的题先跳过、把暴力解的分数拿满再做优化。这些东西不在任何一本算法书里,但踩过坑的人都懂有多重要。

4.4 更新节奏与跟你一起走的约定

最后说一下这个系列的更新节奏。我给自己定的目标是每周至少三到四篇,每篇聚焦一个具体的问题或知识点,不贪多,但会写透。内容形态包括学习笔记、题目拆解、踩坑记录、复盘总结等。

我更希望的是,这个系列能成为一个双向互动的空间。如果你在做某道题时卡住了,欢迎把卡壳点发在评论区,我会定期挑有代表性的问题,在后续文章里拆解。也许你觉得某个专题特别难,比如动态规划,那我可以把某个专题的预定计划提前。对我来说,"算法日迹"不是单向输出的教程,而是一群人一起从同一个起点出发、互相照应着往前的记录。

5. 如果你也想开始:一些掏心窝的建议

5.1 零基础能学吗?我的判断是能

很多读者可能会问:我大学没学过算法,代码都写得磕磕绊绊,能跟下来吗?我的回答是:能,但要有正确预期。

我自己就是从"连递归都理不清"的水平重新起步的。你不需要先读完一整本算法书才能开始,那反而容易在理论里打转。更有效的方式是直接上手做题,在做题中补理论。先有一点最基础的编程能力,会写循环、会定义函数、会用数组和字典,就可以开始第一个专题了。遇到不懂的概念,比如复杂度、递归展开过程,就去查专题文章,在实践中补基础,比先啃三百页书再做题要高效得多。

但也要把丑话说在前面:如果期待每天花十五分钟、两周后就脱胎换骨,那基本是幻想。算法的提升是一个缓慢的、非线性积累的过程,可能需要两三个月才会感觉到明显的质变。开始之前给自己一个合理的心理预期,反而更容易坚持下来。

5.2 选一门你写得最顺手的语言

经常有人问我:"学算法用什么语言好?"我的建议很直接:用你平时写起来最顺手的那门语言,不要为了刷题特地换一门新语言。

如果你平时用Python,那就用Python。它的语法简洁,列表、字典这些容器用起来很直观,能让你把注意力集中在"算法的思路"而不是"指针到底指到哪"这类语言细节上。如果你平时写Java或C++,那就继续用。做到后面你会发现,算法核心是思路本身,语言只是表达思路的工具。最怕的是三天两头换语言,每次都在熟悉语法,永远进不到解题的深度里去。

5.3 建立属于你自己的反馈循环

一个人刷题很容易陷入"今天做不出题-挫败-明天不想开电脑"的负循环。要打破它,我的经验是建立一个正向的反馈循环,核心就八个字:少量、记录、复盘、重做。

每天不需要贪多,一道题就够。做完之后按我前面说的笔记模板记录一下,那一题就有了你的个人印记。到了周末,把本周的卡壳点重新过一遍,挑两道最典型的题独立重做一次。你会发现,当初让你头疼半天的题,现在能顺下来了,这种确切的进步感是支撑你持续走下去的最好燃料。

如果条件允许,找一个也在学算法的朋友互相监督,每周交换一道自己觉得有价值的题目和解题思路。讲给别人听是一种比自己做题更深入的复习方式,很多你以为懂了的点,一旦要讲出来就露馅了。这个方法帮我补上了不少知识漏洞。

5.4 关于"必看"和长期主义

回到这个系列的标题。"必看"两个字,放在"梦开始的地方"后面,本意并不是说接下来每一篇都是什么必读经典,而是说:如果你决定跟我一起走这段算法路,那这一篇就是我们共同的起点。它不需要你天赋异禀,不需要你已经刷了大量题目,只需要你愿意承认"我现在还不会"并且"我愿意从这一步开始"。

最后再分享一件真实的小事。那天晚上我注册这个系列的时候,电脑屏幕泛着白光,桌面上躺着一个只写了三行半的递归函数,终端里还留着上次失败的报错信息。那一刻没有豪言壮语,我只是在文档开头打了一行字:"今天起,重新学算法。"后来我明白,梦开始的地方从来不是站在起跑线前的那一刻,而是你经过犹豫和自我怀疑之后,仍然决定迈出第一步的那一瞬间。现在回想起来,很多说得出口的成长,都始于一个深夜朴素的自我坦白。这个系列的下一篇文章已经在路上了,咱们一道题一道题地慢慢往前走吧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询