先交代一下背景,免得大家觉得我在说废话。我大学四年基本就是泡在OJ(Online Judge,在线评测系统)里过来的,从最开始连题目都读不懂的小白,到后来能稳定在周赛里拿名次,中间踩过的坑、绕过的弯路,比你们想象中的多得多。所以今天这篇东西,我就以“老油条”的身份,把OJ题目练习这件事从头到尾捋一遍,从平台选择、刷题路线、核心知识点,到一道题从读题到AC(Accepted,通过)的完整实操流程,再到各种奇奇怪怪的报错怎么修,都给你们交代清楚。
搞OI和搞OJ,很多人以为是同一件事,其实差别不小。OI更多偏向算法竞赛,讲究思维深度和数学功底;而OJ题目练习,覆盖的人群更广,不管是考研机试、找工作笔试,还是单纯想锻炼编程能力,都绕不开它。像最近热度很高的华为OJ、东华OJ,还有各类高校自建的OJ系统,本质上都是给你一个在线做题、自动判分的环境。你提交代码,系统跑测试数据,告诉你对还是错、超时还是内存爆了。这个机制听起来简单,但真正能坚持刷下来的人,不多。
这篇文章适合谁看?零基础想入门算法练习的,刷题刷到瓶颈感觉没进步的,准备校招笔试想短期突击的,想带学生搞OJ训练的老师,都可以参考。我会把我在多个OJ平台上折腾出来的真实经验、容易忽略的细节、以及一些“课本上不会写”的心得,一并摊开讲。内容不装高深,尽量说人话。
1. 为什么非要在OJ上刷题?这和平时自己写代码有多大区别
很多人一开始会觉得,我代码能跑通、能出结果不就行了,为什么非要去OJ上被评测系统“刁难”?这个问题我当年也疑惑过,直到被现实狠狠教育了几次才明白。
1.1 自动评测到底在“评”什么
你在本地IDE里写的代码,跑起来结果看着对,不代表这题就过了。OJ系统的评测逻辑很直白:它准备了一组你根本看不到的测试数据,把你的程序丢进去跑,然后对比输出结果和标准答案。注意,是“多组数据”而不是你手动验证的那一两组。这意味着你的代码不仅要正确,还得足够稳健,能处理各种边界情况。
举个例子,你写一个排序程序,自己测试了5个数排好了,觉得没问题。但OJ的测试数据里可能包含100000个数、所有数都一样、数字是负数、数字是最大值边界,甚至输入为空的情况。任何一个边界没处理好,就是WA(Wrong Answer)或者RE(Runtime Error)。这就是OJ和平时写代码最大的不同:它逼着你去想“这个逻辑在所有情况下都成立吗”,而不是“当前这组数据能过就行”。
另外还有两个隐藏的评判维度:时间和空间。OJ会给每道题设定时间限制(比如1秒)和内存限制(比如128MB)。你的算法复杂度太高,即使答案正确,也会TLE(Time Limit Exceeded,超时);数组开得太大或者递归层数过深,就会MLE(Memory Limit Exceeded,超内存)。这些在本地开发里基本不会遇到,但在OJ里,它们是和答案正确性同等重要的硬指标。
1.2 把“写代码”升级成“设计算法”
我自己带过不少学弟学妹,发现一个普遍现象:平时课程作业写得很溜的人,一到OJ上就被打回原形。原因很简单,课程作业往往只需要“实现功能”,而OJ题目要求的是“用最优的方式实现功能”。同样一道题,暴力解法可能10行就写完了,但数据范围一大,直接超时。你得去想用二分、用哈希、用前缀和、用动态规划去优化。
这里有个很关键的思维转变:真正的高手,拿到题的第一反应不是“怎么实现”,而是“用什么算法”。这个过程不是天生的,就是在OJ上反复摔打练出来的。你刷了足够多的题,看到“求区间最大值”就条件反射想到线段树或RMQ,看到“最短路径”就想到Dijkstra或Floyd,看到“子序列计数”就想动态规划。这种条件反射,是任何书本知识都给不了你的,只能靠大量练习形成肌肉记忆。
所以说白了,OJ题目练习就像程序员界的“健身房”。平时写代码是日常生活,能走能跑就行;但OJ是撸铁,练的是实打实的力量和耐力。你可以在健身房之外散步,但要想在算法这块变强,绕不开它。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 热门OJ平台怎么选:华为OJ、东华OJ和其他主流平台
市面上的OJ系统多如牛毛,刚入门的同学最容易犯的错就是“这个平台做几题,那个平台做几题”,结果哪个都没刷透。我个人的建议是:主力平台选1-2个,辅助平台看需求。下面把我实际用过的几个平台逐一聊一下。
2.1 高校自建OJ系统与东华OJ的特色
东华OJ这类高校自建OJ系统很多,特点是题目偏基础、适合入门,而且配套的课程教学属性比较强。如果你是在校生,学校有自己维护的OJ,我强烈建议你优先刷本校OJ。原因有三。
第一,本校OJ的题目难度曲线通常比较平缓,从输入输出练习到简单的模拟、枚举,再到数据结构、算法,循序渐进,很适合建立起刷题的信心。第二,很多老师会把自己布置的作业同步挂在OJ上,题目和考试考点高度相关,刷这些题就是在复习考试内容,性价比极高。第三,部分高校OJ在期末或者考研复试时,会有本校老师出的类似风格的题目,练过之后会有天然的熟悉感。
东华OJ本身题量不算特别大,但胜在题目覆盖面广,从C语言基础到算法进阶都有,而且它的错误反馈信息比较友好,对新手排查问题很有帮助。我拿东华OJ作为新人的“新手村”,实测下来,让一个零基础的人先在这里做掉100道入门题,再去别的平台,挫败感会少很多。
2.2 华为OJ:瞄准企业笔试和面试
华为OJ近两年热度一直很高,核心原因就是它和华为的招聘笔试直接挂钩。每一年华为校招的机试题目,很多就是从华为OJ的高频题池里抽题或者改编的。如果你想投华为、或者想进类似风格的大型科技公司,这门功课几乎是必须做的。
华为OJ的题目风格和企业实际需求更贴合,比较注重字符串处理、数组操作、逻辑模拟、状态转换这类工程中常见的场景,相对而言,纯粹拼数学思维的高难度竞赛题会少一些。这意味着它考察的更多是“你能不能把需求准确无误地用代码实现出来”,而不是“你能想出多么精妙的数学模型”。这和华为的研发岗日常工作内容是有共性的,所以针对性很强。
使用华为OJ刷题,我建议遵循“真题优先”的原则。它的题库里带“机试”或“华为”标签的优先刷,因为笔试出题往往就是在这些经典题上做文章。做题的时候一定要用C++或者Java,这两个是华为笔试系统最主流的语言选择,Python虽然也支持,但个别考场的环境版本比较旧,容易踩坑。
2.3 洛谷、POJ、HDU等竞赛平台怎么定位
如果你不只满足于就业导向的刷题,想系统提升算法能力,那洛谷、POJ(北京大学OJ)、HDU(杭州电子科技大学OJ)这类竞赛类平台就是你的主战场。
- LOJ(洛谷):社区活跃度最高,题解质量好,有完整的题单体系,而且很多题支持在线评测和讨论,新手和老手都能在这找到适合自己的内容。它的“试炼场”模块就是为进阶设计的闯关式刷题。
- POJ:老牌OJ,题目底蕴深厚,但界面和交互非常古早,评测机偶尔响应慢,部分题目的数据也偏老。建议用来刷经典的算法题,不太建议作为日常主力。
- HDU:题量巨大,很多集训队和老师会直接布置HDU的题单,它的“Problem Archive”按算法分类,适合按专题练习。
这几个平台各有侧重,我的经验是:打基础用东华OJ或洛谷的入门题单,抓面试用华为OJ,练竞赛思维再上Codeforces、洛谷的高阶题单。切忌贪多,平台只是工具,核心是保持刷题的节奏感。
3. 从零到一:一条可落地的OJ刷题路线与核心知识点
刷题这件事,最怕的就是“打开题库、随机抽题、做不出来、关闭网页”。没有体系的学习效率极低,而且很容易产生“我都做了几十题了怎么还是不会”的挫败感。下面这条路线是我自己趟出来,也带过不少人走通的,按阶段推进,每阶段的重点和验收标准都很明确。
3.1 第一阶段:输入输出与语言基础(约50题)
很多新手在OJ上遇见的第一个障碍不是算法,而是输入输出。尤其是C/C++的scanf/printf、字符串的读取、多组数据的循环处理,还有Java的Scanner类,Python的input().split(),这些基础如果不熟练,任何题都做不顺。
这一阶段不用追求难度,目标是:彻底搞懂OJ题目的标准输入输出是怎么读、怎么写的。多组数据的情况怎么控制循环结束?读到文件末尾(EOF)怎么办?什么时候用while循环读?这些都要练到闭着眼睛都能写。推荐题型:A+B问题、排序输出、字符串反转、简单模拟。
实操心得是:这一阶段就该把语言核心知识巩固牢。结构体怎么定义、排序函数怎么写、数组和字符串的底层区别是什么,这些细节决定了后续写题的速度。
3.2 第二阶段:基础算法与数据结构(约80题)
第二阶段才是真正的“算法入门”,核心覆盖枚举(暴力)、二分查找、双指针、前缀和与差分、栈、队列、链表、基础二叉树。
这阶段的核心是“复杂度意识”的养成。做题前先看数据范围,判断暴力能不能过,过不了再想优化策略。比如:n <= 10^5的时候,O(n^2)基本必挂,你得考虑O(n log n)或O(n)的方案。这种意识不通过大量练习,是没办法真正内化到写代码的习惯里的。
每做完一道题,强烈建议去“看题解”,但看题解有讲究:先自己真想不出来再看,看完之后必须自己重新写一遍代码,然后去对比自己的解法和题解的差异。差异就是你的盲区,很多人刷题进步快,就是胜在这一步。
验收标准:随便给你一个“数组中找和为target的两数下标”这种题,能1分钟内反映出来用哈希表O(n)解;看到“连续子数组的和”能想到前缀和。有这感觉,基础就过关了。
3.3 第三阶段:高频算法进阶(约100题)
进入这个阶段,就可以系统推进刷题了。重点掌握以下专题:动态规划、图论(最短路与最小生成树)、搜索(DFS/BFS)、并查集、贪心算法、常用STL容器的高级用法。
以动态规划为例,很多新手一看就懵,其实动态规划的核心就是“状态定义”和“状态转移方程”。怎么定义状态?这决定了解法是否能行。背包问题、最长上升子序列、编辑距离,每个经典模型都有固定的套路。通过大量刷题,看到特征立刻判断属于哪类DP模型,就能少走弯路。
这个阶段需要养成“刷题—总结—回顾”的习惯。每做完一个专题,停下来把这一类的套路整理成笔记,隔几天回来看一遍,确保不是做完就忘。建议用表格把自己的做题情况记录一下。
| 专题名称 | 经典题量 | 核心模板与技巧 | 常见误区 |
|---|---|---|---|
| 动态规划 | 25-30 | 状态定义、转移方程、滚动数组 | 状态定义不完整或漏初值 |
| 图论最短路 | 10-15 | Dijkstra、SPFA、Floyd | 忽视负权边、数组越界 |
| DFS/BFS | 15-20 | 递归回溯、队列层次遍历 | 忘记标记访问、栈溢出 |
| 并查集 | 8-10 | 路径压缩、按秩合并 | 合并时写错根节点 |
| 贪心 | 10-15 | 排序+选择策略 | 没有证明贪心正确性就套用 |
3.4 刷题节奏怎么安排:每天多少题最合适
这里有个需要特别指出的点:刷OJ的进步不是线性的。很多人一上来猛刷50题,感觉脱了一层皮,然后歇一周不想碰,这种节奏基本是无效的。我建议的是“每天适量、持续不断”的策略。
基础阶段每天3-5道,保持手感就够了。进阶阶段每天2-3道硬骨头,加上改错题,就差不多了。最重要的是“连续”,哪怕某天状态特别不好,至少也要做一道水题保持节奏,不能出现连续3天以上的空窗期。
我曾有个学妹,每天雷打不动做2道题,周末总结一次,坚持了四个月,从刷题小白到拿到国内一线大厂的实习offer。她速度不算快,但胜在稳定。反观那些“突击式刷题”的同学,效果往往都一般。
4. 一道题从读题到AC的完整实操:我把过程拆给你们看
理论说再多,不如带你走一遍一道题从“看到题目”到“评测通过”的完整流程。我拿一道经典的“华为OJ-字符串最后一个单词的长度”来举例,这道题做过的同学应该不少。
4.1 第一步:精读题目,划出关键信息
很多WA都是因为读题不仔细造成的。我见过太多人题目没读完,想当然地以为是要输出整个单词,结果题目问的是“最后一个单词的长度”。做题一定要把几个关键信息先圈出来:输入格式、输出要求、输入范围限制、边界条件。
这道题的核心是:输入一个字符串,可能包含空格,要求输出最后一个单词的长度,字符串长度可以很大。知道这个之后,你才能判断用什么手段处理字符串。
4.2 第二步:确定算法思路和复杂度
这道题最简单的做法是从字符串末尾往前遍历,跳过末尾空格,然后数到遇到空格或字符串开头为止,计数就是答案。这样做的时间复杂度是O(n),在任意数据范围下都能通过,空间复杂度O(1),不需要额外数组。
这里我提一个细节:很多人会本能地想到用split函数按空格切分,然后取最后一个片段。这样写没问题,但如果字符串很长、空格很多,切割会额外消耗时间和空间。更关键的是,如果末尾有多个空格,一些语言的split处理逻辑会和预期不一致,很容易WA。所以,用“从后往前扫”的方法,不仅能绕开这些坑,代码也更简洁。
cpp复制#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
getline(cin, s); // 注意:要用getline读整行,cin >> 会在空格处断开
int len = 0;
int i = s.length() - 1;
while (i >= 0 && s[i] == ' ') {
i--;
}
while (i >= 0 && s[i] != ' ') {
i--;
len++;
}
cout << len << endl;
return 0;
}
4.3 第三步:编写代码时注意输入输出细节
ACM/ICPC风格的OJ只认证程序输出和预期输出完全一致,多一个空格、少一个换行,都算WA。所以输出格式一定要严格看题。这道题要求输出一个整数加换行,那就老老实实cout << len << endl。有些OJ对endl和\n的处理效率有细微差别,但在这题的规模下无所谓,重点是把逻辑写对。
输入方面,因为字符串里可能有空格,不能用cin >> s,它会在空格处截断。必须用getline读取整行。这个细节,新手经常踩坑,我在学校带人练习的时候,这道题至少有一半人是挂在输入上。
4.4 第四步:本地测试与提交自测
写完后不要急着提交,先把测试用例在心里过一遍:正常情况(只有一个单词)、末尾有空格、全是空格、单个字符,把这些自己先在本地跑一遍。然后提交前,再看一眼题目给的数据范围,确保数组不会越界、循环不会死循环。
提交上去之后,如果返回AC,说明这题拿下了。如果是PE(Presentation Error)多半是输出格式问题,比如多了或少了空格、空行;如果是RE,大概率是越界或字符串访问出了问题;这些都对应的改就行。
4.5 第五步:事后复盘总结
这是最重要的一个环节,但绝大多数人会忽略。做完一道题,哪怕AC了,也应该花几分钟想想:我还能不能再优化?如果数据范围再大10倍,我的代码会不会挂?这道题的算法套路还能用在什么场景?
这题虽然简单,但背后反映的是“字符串边界处理”能力。后续你刷到“翻转字符串里的单词”、“字符串中的第一个唯一字符”这些题,都会用到类似的处理思路。把简单题里学到的东西沉淀下来,后面遇到复杂题才能举一反三。我在这个环节的心得是:用一句话把每道题的核心收获写在代码注释顶部,后面回头看的时候效率非常高。
5. 常见报错与排查技巧:从CE到TLE的完整自救指南
在OJ上提交代码,不怕报错,怕的是报错了你看不懂、不会查。每个OJ的反馈虽然语言略有不同,但核心也就那么几类。我把最常见的几个挨个聊一下,顺带讲排查思路。
5.1 CE(Compile Error)编译错误
CE是所有错误里最好排查的,因为OJ会把编译器的详细错误信息反馈给你。你只需要把代码复制到本地对应版本的编译环境里编译一遍,就能看到同样的问题。
不过要注意版本差异,特别是C++。有些OJ用的编译器比较老(比如C++98),可能不支持C++11的新语法,比如auto、unordered_map、范围for循环,都会CE。我见过有人因为这个问题挂了半天没搞明白。建议做题前先确认OJ支持的编译器版本和语言标准,严格按照环境来写代码,C/C++尽量用兼容性高的写法。
5.2 RE(Runtime Error)运行时错误
RE最常见的原因有两个:一是数组越界或访问无效内存,二是递归栈溢出或除零错误。排查RE,先定位到出错的数据范围:题目说数组最大N=100000,你就开一个100005的数组,预留几个位置避开边界。判断循环里是不是有除以0的可能,或者取余时用了0作为模数。
还有一个偶发的RE原因是递归深度。有些题目DFS的递归深度可能达到几万层,系统栈容易爆,这个时候就要考虑改写成非递归形式,或者使用显式栈模拟。
5.3 TLE(Time Limit Exceeded)超时
TLE是所有错误里最让人崩溃的,因为代码逻辑可能全对,但就是跑得不够快。碰到TLE,按下面这个顺序排查:
- 看自己算法的时间复杂度是多少,在题目的数据范围下是否能过。
- 检查是不是有多余的循环、重复的计算。比如双重循环里重复调用某函数,函数内部又套了循环。
- 检查输入输出方式,C/C++用
cin/cout有时候会卡常,可以把ios::sync_with_stdio(false)和cin.tie(0)加上;如果还卡,换成scanf/printf实测往往有效。 - 如果是STL使用不当,比如在循环中频繁
erase、insert,可以换成双指针、数组、或者合适的数据结构来优化。
我还遇到过一种很玄学的TLE:同一道题,代码没问题,但是用Java提交就超时,用C++就能过。这种时候也别较劲,比赛和面试环境里,选对语言本身就是策略的一部分。
5.4 WA(Wrong Answer)答案错误
WA是排查成本最高的错误,因为OJ只告诉你“答案不对”,不告诉你哪里不对、对哪些用例不对。这时候能做的是:
- 重新读题,确认自己没有理解偏差,尤其是输出格式、大小写、空格、精度要求。
- 自己构造边界数据测试:最小数据、最大数据、全一样的数据、无解的数据、负数、空串等。
- 看讨论区有没有人分享坑数据。很多经典老题的讨论区,前人踩过的坑都写在里面,会用好讨论区能省大量时间。
- 检查算法整体逻辑,特别关注循环边界、条件判断的边界等。
有一种很隐蔽的WA是精度问题。比如要求保留小数点后6位,你用printf("%.6f\n", ans)就得注意浮点数舍入和默认精度,在计算过程中尽量用double而不是float。
5.5 MLE(Memory Limit Exceeded)超内存
MLE一般是因为数组开太大,或者使用了过多的静态分配。排查思路是:根据题目的空间限制(比如128MB),计算一下自己的数据结构和分配是否超出。一个int是4个字节,开一个1000000的int数组就是4MB,几个大数组一叠加就爆了。
优化方向几个:能用 int 就用 int,不要为了保险全都开 long long;能不用大矩阵就不用大矩阵,用一维数组手动映射二维下标;动态规划用滚动数组,把二维降到一维;不要用递归栈的方式存储过多的中间状态。
5.6 各种报错优先级速查表
| 报错缩写 | 含义 | 最常见原因 | 优先排查方向 |
|---|---|---|---|
| CE | 编译错误 | 语法错误、版本不兼容 | 本地编译对比 |
| RE | 运行时错误 | 数组越界、栈溢出、除零 | 边界检查、递归改循环 |
| TLE | 超时 | 算法复杂度太高、IO卡常 | 换算法、优化IO |
| MLE | 超内存 | 数组过大、状态冗余 | 压空间、滚动数组 |
| WA | 答案错误 | 逻辑错误、边界遗漏 | 重读题、构造边界用例 |
| PE | 格式错误 | 输出空格或换行不对 | 对照题目输出格式检查 |
6. 独门刷题心法与学习技巧:怎样让刷题效果翻倍
前面把平台、路线、流程、报错都讲完了,最后这部分算是我私心最想分享的,因为很多人不是在平台和难度上输的,而是在“方法”上输的。我结合自己练了几年OJ的经验,提炼几条可能不是那么“常识”的建议。
6.1 卡题超过1小时就放下,但别放过
“卡题”是刷OJ的家常便饭。我见过特别多的人,一道题卡了一整天,死磕不出来,最后直接心态崩了,连OJ都不想再碰。我个人的习惯是:一道题如果超过一个小时(简单题超过半小时)还没有思路,就先放下,去看题解或者讨论区,把别人的思路看懂。
但这不意味着“放过这道题”。看懂题解后,一定要把代码自己从头到尾写一遍,然后对着题解找到自己卡住的思维断层点。这个“断层点”才是你真正学到东西的地方,比AC本身更有价值。把每道题的思维断层点记到自己的错题本里,每周回顾一次,进步速度会非常明显。
6.2 从“刷题量”思维切换到“分类总结”思维
刷到后面你会发现,OJ上的题虽然多,但思路模型其实是有限的。所有的动规题,拆开来看就那么几种状态转移模板;所有的图论题,要么是最短路、要么是生成树、要么是拓扑排序。
所以我的建议是,按专题分类刷题,而不是随机乱刷。每次集中精力搞定一个专题,刷的时候总结这类题的共同套路,然后做几道变式题检验自己是否真的理解了。用表格把每个专题的套路记下来,隔段时间回来看,比单纯堆题量有效得多。我也经常说,刷100道随机题,不如把同一个专题的20道题吃透。
6.3 多语言对比,理解会更通透
如果你学的是C/C++,建议偶尔用Python把同一道题写一遍。Python的代码更直观,字符串和容器的操作非常方便,写起来快;但Python在运行性能上又不够快,所以它能帮你反推算法的复杂度是否合理。如果你主要用Python刷题,我也建议至少把C++的STL常用操作学一遍,因为很多题解是用C++写的,你要能看得懂、能对比参考。
我自己刷题时会刻意用不同语言实现同一道题。这个过程不是多此一举,而是帮你从“语法层”跳出来,从“算法层”理解问题。语言只是工具,思路才是核心。
6.4 善用OJ的讨论区和题解,但别依赖
几乎每个OJ的讨论区都藏着一堆好内容,尤其是老题的评论区,各种测试数据、坑点提醒、竞赛选手的解法讨论都有。会查讨论区的人,刷题效率能提升一个档次。但我必须提醒一句:不要一不会就看题解,也不要一AC就完事不再看别人的解法。
看题解的正确姿势是:自己先想,真不会后看,看完后对比自己的思维盲区,然后自己独立写一遍,最后再去看别人的优秀解法,有没有更优的思路或更巧妙的实现。这样一道题才算是真正吃透了。我见过很多人是“看题解觉得自己会了”,关上题解自己一写又是废话连篇,这就是看题解只看不练的后果。
6.5 参加周赛和定时训练,逼自己进入状态
最后这点我最想强调。平时慢慢刷题是一种状态,但很多OJ平台(比如LeetCode周赛、Codeforces的Round)都有定时比赛,在规定时间内做几道题,这种状态是完全不一样的。平时你卡题了可以慢慢想,比赛时你必须快速判断取舍、合理分配时间、控制心态。
我建议刷题到一定阶段后,每周固定参加一次周赛。哪怕排名靠后也没关系,关键是体验“限时高压”的感觉。多次训练之后,你在笔试或者复试机试时面对题目的心态会完全不一样,不容易慌。有些同学一上机试就手心冒汗、脑子空白,就是平时缺少这种限时训练。定时OJ训练,在我看来是性价比最高的模拟实战方式。
7. 关于OJ题目练习,最后再唠叨几句
我个人练了这几年OJ,最大的体会不是“刷了多少题”“拿到了什么奖”,而是思维方式的变化。以前遇到一个问题,脑子里第一反应是“有没有现成的函数”,现在第一反应是“这个问题的规模是什么、复杂度能不能接受、最优解应该是什么结构”。这种思维习惯直接影响了我写工程代码的质量——更少的内存消耗、更快的执行速度、更稳的边界处理,全都是从OJ那些日复一日的提交里练出来的。
如果你现在还在纠结“我是不是不适合刷题”“为什么别人AC得那么快”,我的建议是:先别管别人,按照自己的节奏把基础题啃下来,把每周的总结做了,把每个报错排查清楚,坚持三个月,你回头看第一周做的题,会明显感觉到自己变了。OJ这条路没有捷径,唯一的捷径就是“持续的、有方法的练习”。
最后给大家留个小建议:刷题时养成记录代码和笔记的习惯。每道题写上自己的思路、复杂度、踩坑点、AC的日期,做成自己的个人题库。这个库,才是你刷题路上最宝贵的资产。这些东西在任何平台的题单里都找不到,它是属于你自己的成长轨迹。等你有天回头翻这些记录,看到“这题卡了两天”、“这题WA了11次终于过了”的时候,你一定会感谢当年那个认真死磕的自己。
