☰
蓝桥云课算法打卡第27天:刷穿Lv.1基础题全记录
2026/10/16 16:16:03 网站建设 项目流程

从2月21日开始到今天,我在蓝桥云课平台保持每天固定的算法打卡节奏,算上今天2026-03-19刚好是第27天。今天的计划相当明确:把平台Lv.1难度里“绝大部分题”全部清掉,不让一块基础短板残留。说实话,这个难度层级在很多人眼里是“热身区”,点开几道题AC了就直接冲Lv.2。但我自己做下来才发现,一天想稳定清完几十道Lv.1题、还能保证每道都理解到位,比想象中费脑子。这篇文章就当第27天的完整记录:Lv.1的题目到底在考什么、我踩了哪些坑、用什么节奏刷完,以及下一步Lv.2我打算怎么接。

如果你正在做算法打卡、准备蓝桥杯,或者刚学完数据结构不知道怎么落地,这篇应该对你有用。我不会只列“今天做了哪些题”,那没意义。我更想聊的是“为什么第27天才集中清Lv.1”以及“清完Lv.1之后我的能力到底发生了什么变化”。

1. 为什么选在第27天集中清空Lv.1题单

1.1 前26天我并没有跳过Lv.1,而是“穿插着做”

说清楚一个前提:这27天不是前26天都在学高级算法、第27天突然回头做基础题。我实际采用的节奏是每天先用半小时到一小时处理Lv.1中还没做的题目,完成当天主任务后再回来补。这么做的原因很直接:Lv.1是绝大多数后续题目的“前置依赖”,如果堆到最后一天再集中刷,你对基础题型的敏感度根本达不到比赛要求。

比如双指针类题目,Lv.1里可能就考最简单的“有序数组两数之和”;到了Lv.2,同样的双指针会结合滑动窗口、链表找环、字符串匹配。你不在早期把这些基础形态做熟,后面看到复杂题根本不知道它其实是“两个指针同向移动”的变体。

所以我在前26天做了一件很多人容易忽略的事:每接触一个新专题,就回到Lv.1找对应的最简版本,先确认“最简模型”已AC,再往前推。到了第27天,Lv.1题单剩下的题已经不多,但都是些前期为了赶进度没有深究的边角题。一天清完,实际上是对前26天的习惯做最终校验。

1.2 Lv.1在蓝桥云课题单里的真实定位:不是简单,而是“信息降噪”

如果你打开Lv.1的题目列表,第一反应大概率是“这也叫算法题”?很多题模板就几行,输入输出已经给好,甚至不用考虑复杂边界。但我刷完绝大部分之后,对它的定位有了新的判断:Lv.1考查的重点从来不是代码能力,而是“把题目描述翻译成约束条件”的能力。

比赛中的高手和新人之间最大的差距,往往不是算法背得多熟,而是谁能更快地从题干里找出边界条件和特殊输入。Lv.1题单恰恰是把这种能力拆成了最细的颗粒度给你练。举个例子,很多Lv.1题目会写“保证输入为整数,最多不超过10^6”,你看第一眼觉得是废话,但这句废话直接决定了你能不能开数组、需不需要用long、能不能用O(n^2)算法。第27天我把这类约束专门做了个表格,发现同一道题只要把数据范围改掉,难度直接从Lv.1跳到Lv.3。

所以我的结论是:Lv.1不是用来“找自信”的,而是用来“校准阅读习惯”的。这个认知不建立,后面刷再多题都会在同一个地方反复摔跤。

2. Lv.1题单的四类题型解剖:考点比想象中立体

2.1 输入输出与基础模拟:不只是print那么简单

Lv.1中数量最多的一类就是模拟题,给你一段实际场景的描述,让你照着流程写代码。我第一次做这类题时觉得繁琐,不愿意仔细读题。第27天重新做的时候,我用了一个新方法:先不写代码,单纯把题干的动作步骤用注释列出来,再对照样例推演一遍。

这个方法让我意识到,模拟题写得慢的根源不是编程能力,而是没有把自然语言转成状态机。很多模拟题的题干看起来是散文,但它实际上在描述一个有限状态的变化过程。你只要抓住“有哪些状态、每个输入触发什么状态迁移、什么时候终止”这三个要素,代码结构自然就清晰了。

应对于快读快写的场景,我还测过不同语言的IO方式差异,下面这张表是我在本地实际跑过的结果:

做法百万级整数读取耗时适合场景
Python的input()逐行约1.2秒数据量小、练习验证
Python的sys.stdin.buffer.read()约0.15秒大规模输入、比赛现场
Java的Scanner约0.9秒日常练习方便阅读
Java的BufferedReader约0.3秒比赛高频输入
C++的cin且关闭流同步约0.2秒几乎通用

你有可能会想:才差1秒,至于吗?至于。蓝桥云课这类评测系统对Python的时间限制通常不宽松,如果一道Lv.1的模拟题数据范围给到10^6,用input()读入就直接超时,而用sys.stdin.buffer.read()就稳过。这个经验在Lv.2的大数据量题目里更关键。

2.2 枚举与二分边界:绝大多数Lv.1题的核心突破口

Lv.1里到处是“暴力枚举”能解的问题。比如给你一个数组,问是否存在两个数满足某个条件,你写两层循环也能过。但我刷完后的体会是:每道枚举题都值得再想一想“如果数据范围乘10,我还能这么干吗”,因为比赛里的难题几乎都是枚举的优化版本。

以“查找某个值是否存在”为例,Lv.1约90%的题目都能用线性扫描处理。但最基础的二分查找题会要求你把复杂度从O(n)降到O(log n)。这里最反直觉的地方是二分查找的边界写法,我统计了自己做错的题,发现近半数不是思路错,而是while循环条件是left < right还是left <= right没想清楚。

我第27天给自己定的规则是:所有二分题,一律采用“左闭右开”写法,也就是left = 0,right = length,循环条件是while left < right。这么做的原因是左闭右开区间中,left和right的收敛关系非常直观,不会因为“等于”情况的处理方式不同而出现死循环。虽然网上有人用闭区间写法也写得很溜,但你在比赛中没有时间去试错,固定一种可靠写法是最优解。

2.3 栈、队列与哈希:数据结构在Lv.1里的“轻量级应用”

Lv.1对数据结构的考查很少让你手写平衡树,它主要考的是“你会不会在恰当的时候用底层数据结构”。例如括号匹配、单调栈最基础的版本、用哈希统计出现次数,这些都是Lv.1的常客。这类题对熟悉语言内建库的人十分钟能写完,但对不熟悉库函数的人会卡很久。

我在第27天集中处理时发现了一个有意思的现象:不少人的问题不是数据结构不会,而是对语言API不熟,导致明明想到了正确解法,却在实现细节上浪费大量时间。比如Python里defaultdict和Counter的区别,Java里PriorityQueue默认是小顶堆,C++里unordered_map的遍历顺序不保证,这些细节如果平时不刻意记,Lv.1的题也能让你写出一堆bug。

我建议你专门花一点时间把所用语言的常用容器API过一遍,甚至直接写在笔记里。这些内容不属于“算法知识”,但它们是比赛中的硬通货,没有它们,你的算法根本跑不起来。

2.4 数论与组合数学的入门:Lv.1也藏着数学思维

不要以为Lv.1只有模拟和枚举。有一类题表面上是求“最大公约数”“最小公倍数”、判断质数、计算排列组合数量,这些实际上是数论和组合数学的入口。这类题很容易被忽视,因为它们“看起来像数学题”,很多刷题的人会直接跳过,直到Lv.3遇到模运算和组合数取模才慌。

我刷完Lv.1后的建议是:至少掌握三种数学工具——辗转相除法求最大公约数、线性筛求质数、以及快速幂的基本写法。这三个知识点的代码量都不大,却在后面许多压轴题里反复出现。Lv.1中它们的出现形式极其直白,正好适合把模板刻在脑子里。

比如线性筛的核心,下面的Python写法大约只有十行:

def get_primes(n): is_prime = [True] * (n + 1) primes = [] for i in range(2, n + 1): if is_prime[i]: primes.append(i) for p in primes: if i * p > n: break is_prime[i * p] = False if i % p == 0: break return primes

这段代码里最关键的是break条件:每个合数只会被它的最小质因子筛掉一次,所以总复杂度是O(n)。如果去掉内层循环里的取模判断,代码会退化,但时间复杂度会变成接近O(n log log n)之外还可能出现重复标记。这种“为什么这样写”的理解深度,才是Lv.1题真正训练你的东西。

3. 刷穿Lv.1最容易翻车的三个技术点

3.1 读入超时与字符串处理的隐形成本

第27天我遇到的第一道坎,就是一道看起来极简单的字符串统计题。思路秒出,但是提交后超时。我后来发现罪魁祸首就是字符串拼接。Python里用“+”拼接字符串会不断创建新对象,当循环次数达到几十万次时,这个开销会被无限放大。正确做法是收集到列表再join,或者直接用StringIO。

这类性能问题不会在少量数据时暴露,题目给的数据量一大就直接超时,而Lv.1的数据范围往往就踩在“让你刚好超时”的临界线上。这个经验后来帮我在Lv.2的字符串题里少走了很多弯路。你做题时,只要发现某个操作在循环体内使用了“字符串拼接、频繁创建临时列表、递归里重复计算”,就应该警觉。

3.2 数组越界与边界条件:肉眼最难看出的错误

我在第27天集中清题时统计过一次提交记录,发现“数组越界”占据了我所有运行时错误的一半以上。原因非常典型:写循环时想当然地把下标写成从0到n,但实际需要处理的是从1开始;或者循环里存在i-1、i+1这类表达式,没有在边界处做保护。

处理边界问题的有效手段是:第一步判断每个数组访问是否都落在合法范围;第二步准备长度为2或3的最小测试用例跑一遍;第三步用题目给出的最大边界数据做一次压力验证。很多人做题只测样例,样例过了就提交,结果样例往往只测了最中间的情况,边界全要靠自己想。

我在第27天打卡时,为所有涉及下标的题统一加了一个规则:只要循环体内出现i-1,循环就从1开始;只要出现i+1,循环就到n-1结束。这个规则很笨,但它直接免疫了一整类越界bug。

3.3 取模、溢出与浮点数比较:数学题里的隐形杀手

Lv.1的数论题里经常要求结果对某个数取模。取模本身不难,但很多人会忽略中间计算可能溢出的问题。拿C++举例,如果两个int相乘再取模,结果可能已经溢出成负数;如果中间结果是long long也可能在某些极端题目里溢出。稳妥做法是每一步计算都取模,并尽量使用64位整数。

浮点数比较则是另一种坑。直接判断“a + b == c”在浮点数世界里不靠谱,比如0.1 + 0.2的结果并不是0.3。这时需要设置一个极小的误差范围,例如fabs(x - y) < 1e-9,才算是比较安全的做法。

我想特别提醒一点:我发现“该用long long时用了int”这种失误,在我做Lv.1的过程中出现了至少三次。凡是题目里出现“10^9”以上的数据范围描述,眼睛就会自动告诉大脑用long long。另外,Python不存在这个问题,但也正因为如此,很多用Python刷题的人一旦转去写C++或Java,特别容易在类型上翻车。

4. 我的“逐题清单”工作流:一天清完不靠蛮力

4.1 先建表再动手:把题目按状态和标签分类

第27天早上,我没有直接打开题单页就开始写代码。我先把所有还没AC的Lv.1题目拉出来,用表格统计每一道题的状态,列了三列:题目所考核的知识点、预计完成时间、实际完成时间。做完这个动作后,我发现自己剩下的题虽然数量不少,但知识点重复度很高,主要集中在模拟、基础枚举、简单哈希和字符串处理四类。

于是我先按“相同知识点批量处理”的策略安排顺序。比如今天所有涉及哈希统计的题,我一次性连续做掉,做完后不仅速度快,而且每道题之间能互相印证解法。比起那种随机点开一道就写的做法,这种方式明显更系统,也让我在每道题的解法里看到了同一个套路的不同变体。

4.2 一小时内不AC就标记,不跟一道题死磕

我在刷题时有一条铁规矩:单题思考超过30分钟,就直接看题解,做完标记为“重点复习题”。第27天我同样坚持这个节奏。很多人会担心看题解后印象不深,但我的经验是,只要你在看完题解后马上独立重写一遍,并对关键判断做注释,印象会比死磕两小时深得多。

这里我配了一张第27天状态的简单追踪表,虽然具体题目名称不同,但这个结构你可以直接复用:

阶段目标完成情况
上午第一轮将所有未做模拟题和枚举题AC完成95%
下午第二轮集中解决哈希与字符串题完成100%
下午收尾阶段重刷标记题并整理错因完成80%
晚间复盘输出本篇打卡记录完成

这个流程的底层逻辑很简单:上午大脑清醒时做需要“理解题意”的模拟题,下午处理相对机械的哈希与字符串题,晚间记忆力段适合复习错题。时间分配跟题目难度之间并不是线性的,而是按认知负荷来分配的。这也是为什么“一天清完Lv.1”并不是一句口号,而是确确实实可以被拆解成一个个小目标来完成。

5. 四道有代表性的Lv.1题:从审题到AC的完整思考

5.1 模拟题:把题干翻译成状态机

有一道题大致意思是:某个系统有多个状态,输入特定字符会让系统切换状态,最后输出结束状态。这类题我第一次做的时候圆图吞枣,直接写了一堆if-else,结果没过。后来我学会先画状态表,把“当前状态 + 输入字符 → 下一状态”的关系全部列出来,再翻译成switch或字典。

我现在的做法是使用dict构造状态转移表,把逻辑和数据分离。这样哪怕题目复杂十倍,也只是表格变长,代码不会乱。尤其是当状态数量和输入类型超过5个时,if-else嵌套会让代码丑到看不懂。这个经验后来我在实际项目里处理协议解析时也屡试不爽。

5.2 排序加双指针:同一套解法解决“两数之和”与“三数之和”

我在Lv.1里连续遇到“两数之和”“三数和是否等于目标”这类题。很多人会背解法,但没意识到“两数之和”和“三数之和”背后的双指针模型是完全一样的。对有序数组,用两个指针一左一右向中间收敛,根据当前和与目标值的大小调整方向。这个套路一旦吃透,几乎通吃所有有序数组的求和类问题。

Lv.1的“两数之和”甚至不需要排序,直接暴力也能过。但我建议你无论如何都要试一次双指针写法。原因很简单:Lv.2中,无序数组版本的问题需要先排序再用双指针,而数组里的重复元素会导致去重逻辑,这些都是在“排序+双指针”基础上的增量难度。你如果Lv.1时就把基础模板写熟,后面只是多记几步而已。

5.3 递推题:从暴力递归到记忆化的“顿悟”

Lv.1中有一类经典递推题,比如走台阶问题:每次可以走1步或2步,到达第n级有多少种走法。暴力递归的写法非常简单,但会产生大量重复计算。我当时的顿悟点是:所有重复计算都来源于“同一个状态被多次展开”,只要用一个数组把已经算过的结果存下来,复杂度就会从指数级降到线性级。

这个“记忆化”思想是动态规划的雏形。很多初学者觉得动态规划难,是因为教程一上来就讲状态转移方程,跳过了“为什么需要记忆化”这一步。但在Lv.1的递推题里,你完全可以感受到这个过程的必要性:不记忆,跑不动;记忆了,瞬间过。这种亲自体验比任何理论解释都来得有效。

5.4 卡了我两小时的“简单题”:教训比AC值钱

第27天我有一次印象深刻的卡壳。那题看起来是标准的“判断回文”题,但我提交后连续三次答案错误。后来我打印出处理后的字符串才发现,题目里要求“忽略非字母数字字符”且“不区分大小写”,我却在正则过滤后忘了统一转小写,导致A和a被判断成了不同字符。

事后复盘,让我卡住的不是算法,而是“需求细节的遗漏”。这道题让我反思了一个现象:很多Lv.1题目对条件描述得非常直白,我反而因为觉得太简单而读题不细。这类错误在比赛里属于最可惜的丢分。为此我给自己定了个改不掉的习惯:每道题AC之后,回到题干逐字读一遍,凡是题目中出现“忽略、不区分、至少、至多、非空、升序”这些词,就用荧光笔标出,确保这些限定条件都体现在代码里。

6. 下一步:第28天开始,Lv.2要怎么接

6.1 把Lv.1的解题套路沉淀成自己的模板库

第27天结束后,我不建议直接大跨度进入Lv.2。正确做法是先花一点时间,把Lv.1里频繁使用的模板归类整理:二分查找的边界模板、双指针模板、线性筛模板、快速幂模板、以及各种容器的初始化写法。这些模板不是让你死记硬背,而是让你知道“在什么场景下该翻哪一页”。

我还专门创建了一份自己的“错题记录”:绝不复制整段题解,而是用一句话写下“当时的错误假设”和“正确理解”,比如“对有序数组使用二分时,等于条件要单独判断”“用正则处理字符串时记住先统一大小写”。这些东西比抄十遍题解有用得多,因为它们是真正属于你的认知纠偏。

把模板沉淀好之后,你的代码才会从“每次现场想”变成“调用自己的知识库”。这一点在比赛时间紧张时尤其重要,省下来的时间都用在思考真正的难点上,而不是重写已经写过一百遍的基础结构。

6.2 从Lv.1到Lv.2的三个能力升级方向

进入Lv.2之前,我认为有三个能力需要刻意补强。第一个是复杂度的敏感度:Lv.2的题目会明显提高数据范围,你必须能在读题阶段就大致估算出目标算法的时间复杂度。第二个是状态抽象能力:很多Lv.2题不再是直白地让你“做一件事”,而是让你从场景中提炼出状态和转移条件。第三是代码组织的整洁度:当代码长度超过80行时,函数拆分的必要性会迅速上升,良好的模块化会直接影响你调试时的效率。

如果第28天你刚开始接触Lv.2,不要害怕AC率下降。下降是正常的,说明你正在脱离“复制模板”的舒适区。这时可以退回Lv.1重新练手感,但每次退回都应该带着明确问题:到底缺的是模板、是状态抽象、还是边界考虑?带着这句话回Lv.1补课,比漫无目的地重刷有效得多。

我一直觉得,刷题打卡的意义不在于那个连续天数,而在于每一天都能明确地知道“我的薄弱点在哪里、今天有没有把它补上”。第27天把Lv.1的绝大部分题清掉,对我来说最大的收获不是“数量终于清零”的成就感,而是我终于有了一个完整、干净、可复用的基础题库,以后任何时候需要回头查模板,都能直接定位到具体题型。希望这篇记录也能让你的算法打卡少走一点弯路。

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

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

立即咨询