news 2026/10/22 9:25:41

刷题第一天如何坚持?从数组二分查找搭建可复用的算法学习流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
刷题第一天如何坚持?从数组二分查找搭建可复用的算法学习流程

第一天打开题单的时候,我第一反应是关掉页面。

这不是开玩笑。作为一个当年被“代码随想录 day1”这种打卡计划吸引、又差点在第一天就放弃的人,我太清楚那种感觉了:标题看起来很正能量,评论区一片“打卡成功”,但自己一上手,数组、指针、复杂度、边界条件,每个词都认识,拼在一起就是看不懂,更别提在限定时间里写出能通过的代码。如果你也正处于这个阶段,别急着怀疑智商,这篇文章就是写给第一天的你。我会把自己第一天踩过的坑、后来总结出的方法、以及一道题从“完全没思路”到“AC”的完整心理过程,全部拆开讲清楚。不管你是刚准备找实习,还是单纯想把算法基础补起来,这套思路都适用。而且我保证,看完之后你至少不会觉得第一天是无用功。

1. 刷题第一天最容易被劝退的三个瞬间,以及我的处置方式

很多人以为刷题第一天最难的是“不会做”,其实不是。最难的是“还没开始就觉得自己不行”。我把第一天会遇到的劝退瞬间总结成三类,每个我都亲身经历过。

1.1 瞬间一:题目描述每个字都认识,合起来完全看不懂

我记得自己第一天拿到第一道数组题时,题目里有一个词叫“原地修改”,我当时盯着看了两分钟,心想:原地是什么意思,是要我在原数组上面打滚吗?后来才知道,原地修改就是指不额外开一个新数组,直接在原数组上操作。这种专业黑话在题解里比比皆是,什么双指针、哨兵节点、哈希表、滑动窗口,第一次看到真的像看天书。

处置方式其实特别朴素:把看不懂的名词记下来,当作今天的学习目标之一,而不是当作放弃的理由。第一道题看不懂很正常,因为题解默认你已经具备了一部分前置知识。我第一天给自己定的规矩是:允许自己定义“看懂”——不要求一次看懂所有细节,只要求看懂“这道题是想让我干什么”。比如“原地修改”,我就翻译成“不许用另外的数组,只能动原来的数组”。能把题目翻译成人话,就已经赢了一半。

1.2 瞬间二:别人十分钟 AC,我半小时还在编译错误

这是最容易让人崩溃的时刻,尤其是当你加了几个刷题群,看到别人早上六点发“打卡成功,今日两题”,而自己连一个测试用例都跑不对的时候。我当时的第一反应是:完了,我是不是不适合写代码。

后来我想明白了一件事:别人十分钟 AC 的背后,是他们已经见过几十道类似的题,那些代码几乎是“肌肉记忆”。而第一天的人,连输入输出长什么样都要想半天,速度当然不一样。这不是智商差距,是经验差距。处置方法我只有一条:把“十分钟 AC”这个标准从脑子里删掉。第一天只看一件事——我能不能最终跑通。哪怕花两个小时,只要跑通了,今天就值了。如果跑不通,那也值了,因为你至少知道了自己卡在哪里。

1.3 瞬间三:收藏了一堆优质题解,觉得已经学会了

这个陷阱特别隐蔽。第一天我一旦做不出来,就习惯性去搜题解,看到一篇写得特别好的,逻辑清晰,图文并茂,我一边点头一边收藏,心里想着“哇,讲得真好,我会了”。结果关掉页面让我自己写,脑子一片空白。

收藏不等于学会,看懂不等于能写。这个道理我第一天就懂了,但真正改掉这个毛病花了很久。我的处置方式是:把收藏夹当成“复读机”,而不是“仓库”。收藏一篇题解之后,当天晚上必须关上它,自己默写一遍关键逻辑;写不出来,第二天早上再去看。如果只是收藏不看,那就等于没收藏。后来我把这个习惯叫“反收藏机制”,对抗的就是我们这种“以为存了就会了”的大脑。

2. 开刷前先定死四件事:语言、环境、流程、打卡节奏

第一天最容易犯的另一个错误,是还没想清楚规则就冲进题海。我见过太多人第一天就换了三种语言、两个平台、四套计划,最后啥也没坚持下来。刷题虽然看起来是“做题”,但它其实是个系统工程。开刷前把下面四件事定死,比多做三道题有用得多。

2.1 语言选熟不选新

很多人会有一种错觉:刷题顺便可以学一门新语言,比如用 Python 刷题顺便学 Python。我劝你别这么干,至少第一天不要。刷题时你的注意力应该全部放在“算法逻辑”上,而不是语言语法上。如果你选的是一门不熟悉的语言,你会在“这个函数怎么拼”“这个列表怎么切片”“这个分号是不是漏了”这些问题上消耗掉大量精力,最后失败了你还会以为是算法太难。

选语言就只有一条标准:哪门语言你写起来最顺手,就用哪门。我当时选的是 Python,不是因为 Python 天下第一,而是因为我那会儿最熟的就是它,写起来不用查文档。后来我也见过用 Java、C++、Go 刷题的朋友,坚持得都很好。第一天千万别在这上面纠结,浪费时间。真要学新语言,等刷题节奏稳定下来之后,再考虑用新语言重刷旧题,那时候才是学语言的好时机。

2.2 环境配置:本地调试和在线评测各自承担什么

第一天我先检查了两样东西:本地编辑器能不能跑通最简单的代码,在线评测平台的提交按钮是不是正常。听起来很简单,但真的有人第一天就栽在这上面——本地代码跑得好好的,一提交就报错,最后发现是缩进问题;或者本地根本没配环境,全靠网页编辑器硬写,写长了就难受。

我自己的安排是这样的:本地编辑器负责“调试”,在线评测负责“验收”。也就是说,我先在本地把代码写好、跑通、打上日志看输出对不对,然后再复制到在线评测去提交。这样做的好处是,本地调试你能看到完整的变量变化,可以在关键位置加 print,能真正理解代码在干什么;而在线评测只告诉你对错,不给太多过程信息。对第一天的人来说,能看见中间过程比直接看到“通过”重要得多。另外,我建议第一天就学会用测试用例来验证,不用很多,三五个边界用例就够。比如数组为空、数组只有一个元素、目标值在最前面、目标值在最后面,把这些情况都跑一遍,比盲目提交十次有用。

2.3 一道题的完整处理流:5分钟思考 -> 15分钟实现 -> 复盘

第一天最容易出现的两个极端,一个是想了五分钟没思路就去看题解,另一个是死活不看题解,死磕俩小时不出来。这两个极端我都经历过。后来我给自己定了一个“5-15-无限”流程,第一天执行下来感觉特别稳。

具体来说:先自己思考 5 分钟。这五分钟不是干瞪眼,而是做三件事:第一,把题目翻译成人话,明确输入和输出是什么;第二,想一个最笨的办法,哪怕时间复杂度是 O(n 的平方),只要能跑通就行;第三,在纸上画一画,假设输入是 1、2、3,手动推一下结果会是什么。如果 5 分钟后还是毫无头绪,那就去看题解,但要带着问题去看:我是卡在理解题目,还是卡在想不到思路,还是想到了思路不会实现。

如果 5 分钟内有了思路,那就给自己 15 分钟去实现。超过 15 分钟还没跑通,说明这个思路里有隐藏的坑,比如边界条件处理错了,这时允许再花 10 分钟调试。如果还是不行,果断看题解。第一天的人最需要的是“完整跑通一道题”的成就感,而不是“死磕一道题到底”的英雄主义。把战线拉太长,第二天你就不想打开编辑器了。

2.4 第一天的时间节奏怎么安排

我见过很多人第一天就给自己安排五六道题,结果只完成一道,然后产生巨大挫败感。第一天真的不要贪多,两到三道题就非常够了。我第一天的节奏是:早上第一道题,找感觉;下午第二道题,巩固;晚上第三道题,尝试独立做,全程不看题解。三道题里,前两道允许看题解,第三道不允许。这个安排的核心逻辑是,让难度平缓上升,又不至于太舒服。

另外,时间块不要太散。我第一天试过中午刷一道、晚上刷一道、睡前再看一眼题解,结果发现每段时间都很碎,脑子里刚有点思路就被别的事打断。后来改成每天固定一个 45 分钟的完整时间块,加上一个 15 分钟的碎片时间做回顾。45 分钟里,前面 10 分钟复习昨天的题,中间 25 分钟做新题,后面 10 分钟写复盘笔记。这个节奏坚持下来之后,效率比我之前一天到晚刷手机看题解高得多。

3. 以“数组-二分查找”为例,看一道题如何从懵逼到 AC

说完了心态、环境和流程,接下来聊聊第一天的核心内容。大多数刷题计划,第一天都是从“数组”开始的。这不是偶然,因为数组是最基础的数据结构,它的操作能引出很多经典算法思想。我拿我第一天做的一道二分查找题作为例子,把从“完全没思路”到“AC”的全过程拆给你看。

3.1 为什么第一天要从数组题入手

数组的特点是什么?连续的内存空间、相同类型的数据、通过下标随机访问。这三个特点决定了数组题目的变化多端:你可以用指针遍历它,可以用二分法切它,可以用哈希表记录它里面的元素,还可以在它内部做各种原地操作。换句话说,数组是算法世界里最便于白纸上推演的场景。

我第一天看到题单上全是数组题的时候,还觉得无聊,心想这不就是遍历吗。后来才知道,同样的数组,难度可以从简单到地狱。二分查找就是一个典型的例子:看起来就是“在有序数组里找一个数”,但真正写起来,边界条件能让人怀疑人生。我第一天就死在这上面。

3.2 暴力解法先落地,再谈优化

拿到一道“在有序数组中查找目标值”的题,我的第一版代码写的是暴力遍历。那时候的逻辑特别单纯:数组有序,我直接 for 循环从头到尾找一遍,找到了就返回下标,找不到就返回 -1。这当然能通过最简单的测试用例,但稍微大一点的输入就会超时。

暴力解法的意义不在于“效率”,而在于让我先确认自己对题目的理解没有错。如果连最笨的方法都写不出来,说明我连题目都没读懂。写暴力解的过程会逼着我去定义清楚变量名、边界和返回值,这些是后续优化的地基。我第一天给自己定的规矩是:哪怕知道答案是用二分查找,也先花五分钟写一版暴力解。别小看这一步,它能培养一种很宝贵的能力——把模糊的想法落地成代码的能力。

3.3 二分查找的边界为什么是左闭右开

当我意识到暴力解会超时,下一步就得想更好的办法。“有序数组”和“查找”,这两个词放在一起,几乎就是在明示二分查找。二分查找的逻辑不复杂:每次取中间位置,如果中间值大于目标值,就去左半边找;如果小于目标值,就去右半边找;如果等于,就找到了。但第一天写二分查找,我几乎必然会在边界条件上报错。

问题出在“区间定义”上。我当时写得特别混乱,一会儿 left <= right,一会儿 left < right,一会儿 right = mid,一会儿 right = mid - 1,每次提交都卡在一个奇怪的用例上。后来我才真正理解,写二分查找之前必须先想清楚一个问题:我维护的这个区间,是左闭右闭 [left, right],还是左闭右开 [left, right)?这两种区间对应的写法是完全不同的。

如果是左闭右闭,那 left == right 的时候区间里还有一个元素,所以循环条件要用 left <= right;当中间值大于目标值时,right 要变成 mid - 1,因为 mid 已经检查过了,不需要再包含它。如果是左闭右开,那循环条件要用 left < right,因为 left == right 时区间已经是空的;当中间值大于目标值时,right 直接等于 mid 就行,因为右边界本来就是开的,不会包含 mid。我后来写了一个小口诀:“闭区间收右边界要减一,开区间收右边界不用动。”这个细节就是二分查找的核心,也是第一天最大的绊脚石。用一个具体的例子来推演一下:

假设数组是 [1, 3, 5, 7, 9] ,目标值是 7。如果用左闭右闭的写法,初始 left=0,right=4。mid=(0+4)//2=2,nums[2]=5,小于 7,所以把 left 更新为 mid+1,也就是 3。此时 left=3,right=4,mid=3,nums[3]=7,正好命中,返回 3。一切顺理成章。但如果中间某一步我把 right 写成了 mid,而不是 mid-1,就会出现死循环,因为区间永远在包含已经被检查过的元素。

3.4 一道双指针练习题:为什么快慢指针能省一层循环

第一天的题单里除了二分查找,往往还会出现“移除元素”这类题。我第一次看到“给你一个数组,原地移除所有值等于 val 的元素,并返回新长度”的时候,第一反应是新建一个数组把不等于 val 的元素装进去,再拷贝回来。但这不符合“原地修改”的要求。后来我才知道,这类题的经典解法是双指针。

双指针的思路其实特别生活化。想象一下你在一条窄路上走,前面有个慢吞吞的人挡路,你不会推开所有人,而是找一个空位快速绕过去。快指针负责“探路”,走遍整个数组;慢指针负责“安家”,只记录那些符合条件的元素。代码写出来大概是这个感觉:

def removeElement(nums, val): slow = 0 for fast in range(len(nums)): if nums[fast] != val: nums[slow] = nums[fast] slow += 1 return slow

这个代码表面上只有几行,但它解决的问题非常深刻:我们只用一个数组、一次遍历,就把所有不需要的元素“覆盖”掉了,时间复杂度 O(n),空间复杂度 O(1)。对比我当初新建数组的暴力写法,快慢指针省下的不是一点点开销,是一整块额外内存和一个隐藏的循环。第一天把这类题吃透,你会发现一个规律:很多看似复杂的问题,最后就是在数组上维护了几个位置标记,仅此而已。

4. 提交通过后,我还会做这三件事

很多人第一天写完代码、提交通过、看到一个绿色的“通过”,就心满意足地关了页面。我后来回头看,觉得这个动作太亏了。通过只是起点,不是终点。如果做完题不进行后续处理,那道题过三天你就忘了,等于白做。我第一天开始给自己定了一个规矩:每道题通过之后,必须再花十分钟做三件事。

4.1 分析时间和空间复杂度,给代码写注释

第一件事是回头审视自己的代码,在关键行写上注释,说明这一步在干什么,以及为什么这么写。比如二分查找里的 right = mid - 1,我会注释“因为当前 mid 已经被检查过,下一步要排除它”。别小看这个动作,它在逼我用自然语言重新讲一遍代码逻辑。如果你发现自己讲不清楚某一行,那往往意味着那一行是你抄来的、或者碰巧跑通的,你并没有真正掌握它。这时候就该回头翻题解,把思路补全。

然后是复杂度分析。第一天只需要会看大 O 就够了:你的代码时间复杂度是 O(n),O(n 平方),还是 O(log n)?空间复杂度是 O(1) 还是 O(n)?我自己的方法是问自己一句话:如果数组长度从 100 变成 10000,我的代码运行时间会变成原来的多少倍?如果大概变成 100 倍,那就是 O(n 平方);如果变成大概 2 倍,那就是 O(n);如果几乎不变,那就是 O(log n) 或者 O(1)。用这种“估倍数”的方法理解复杂度,比死记公式直观多了。

4.2 错题复盘:别只抄答案,要写“当时卡在哪”

第二件事是错题复盘。第一天我做题最大的问题是,看题解的时候总觉得“这也太简单了,我怎么没想到”,然后就直接进入下一题。后来我改变了策略:每道没做出来的题,我会在笔记里单独留一块区域,只写三行字——我当时的思路是什么、我在哪一步卡住了、题解用了什么关键思路让卡住的地方畅通了。

比如我做二分查找的时候,笔记里就写着:“我卡在不知道什么时候该用 mid-1,什么时候该用 mid;题解告诉我首先要定义清楚区间是左闭还是右开,区间不同处理就不同。”这短短两行话,比抄一整篇题解都有用,因为它记录的是一种“认知升级”:我不只是记住了答案,我更清楚地看见了自己思维里的死胡同。这个方法我后来推荐给不少朋友,亲测有效。

4.3 把第一天的题提炼成模式模板

第三件事最有远期价值:把题目抽象成模式。第一天你可能只做了两三道题,但你会发现它们背后其实是同一个家族的套路。数组遍历是一个模式,双指针是一个模式,二分查找是一个模式,哈希表计数又是一个模式。我会在笔记里给每个模式建一个小节,记录它的核心代码骨架、典型应用场景、以及最容易翻车的细节位置。比如双指针模式下就记着“快指针负责探路,慢指针负责安家”,二分查找模式下就记着“先定区间,再写边界”,哈希表模式下就记着“查重和计数都优先想哈希表”。

当你把题目提炼成模式之后,你会发现“刷题”不再是一道一道地刷,而是一类一类地刷。第一天可能还看不出这个习惯的威力,但等你刷到三十天、五十天的时候,再回头翻这些模式笔记,会发现自己已经有了一本属于个人的算法手册。这东西的价值,远超那些收藏夹里吃灰的题解。

5. 第一天过后,真正决定能否坚持的是这件事

聊到这里,你可能会觉得:第一天要做的事也太多了吧,又要定环境、又要写暴力解、又要复盘、又要建模式库。我承认,这套流程听起来繁琐,但第一天真的只需要把这些架子搭起来,后面每一天都是往架子里面填内容。而比这更重要的,是一个心理层面的问题:第二天你还愿意打开编辑器吗?

5.1 把目标从“刷完”改成“搞懂”

我在第一天最大的转变,是把目标从“我要刷完这个题单”改成“我要搞懂今天这一道题”。事后回想,这是我能坚持下来的核心原因。“刷完”是一个没有尽头的目标,因为题单永远在更新,题永远刷不完;但“搞懂”是一个可完成的目标,它不要求数量,只要求你在某一道具体的题上真正突破了某个盲区,今天就算有收获。

这种心态的调整影响特别大。因为当你把目标改成“搞懂”之后,你就不会因为别人一天刷五道题而焦虑了。别人刷五道题可能是那五道题他都见过,而你花两个小时搞懂一道题,你今天增加的“理解力”可能比他刷五道还要多。第一天的我并不完全相信这句话,但三十天之后我信了。刷题本质不是比谁看到的题多,而是比谁脑子里沉淀下来的思路多。

5.2 建立最小正反馈:本地记录、周复盘

为了让自己愿意第二天继续,我还给自己设计了一个最小正反馈系统。第一天我就建了一个本地笔记文件,用来记录每天做了哪几题、卡在什么地方、明天的任务是什么。每天晚上完成任务后,我会在文件前面加一行日期和打卡标记。这个动作很轻,但它给大脑一个信号:你今天确实做了点东西。别小看这种信号,它比任何励志口号都更能对抗“刷题毫无进展”的虚无感。

另外,我还做了周复盘。第一天当然还谈不上一周,但我把复盘框架先定下来了:这一周一共做了几题、哪些题第一次就 AC、哪些题卡住了、卡住的题目有没有共同点、下一周我要重点补什么方向。我后来发现,很多人刷题刷着刷着就散了,就是因为从来不回头看。设立复盘机制,相当于给你的刷题计划装上一个导航,它会在你偏离方向时提醒你。

5.3 我踩过的“求快”的坑

最后再分享一个我第一天之后踩过的大坑,希望你第一周就能避开。那是我刷到大概第十天的时候,觉得自己状态起来了,开始疯狂加量,一天最多刷了七道题。结果到了第十五天,我发现自己对前面很多题的记忆变得特别模糊,连当时 AC 的代码逻辑都讲不清楚了。我这才意识到,加量不加质,约等于白刷。那之后我痛定思痛,把每天的题量压回两到三道,但要求自己每一道都能在三天后不看题解独立重写出来。

“能不能独立重写”这个标准,比“当天能不能 AC”严格得多。它逼着我把短期记忆变成长期记忆,把“看懂了”变成“会做了”。第一天你可以不设置这个标准,免得压力太大;但第二天、第三天开始,一定要慢慢引入这个要求。否则你会发现自己刷了一个月,最后能在白纸上默写出来的题目,一只手都能数得过来。

第一天的收获,不应该是几道题的答案,而是一整套可复用的流程:遇到不懂的术语就查、五分钟没有思路就看题解、写代码先暴力后优化、提交通过后复盘、把每个套路沉淀成模板、把目标从“刷完”改成“搞懂”。这套流程我后来用在了很多场景里,不光是刷题,连看框架源码、学新技术栈,都是同一个套路。第一天可能显得很笨拙,但它值得你认真对待。毕竟,只有先把第一天的地基打好,第二天的你才愿意推开编辑器的大门。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 11:03:23

FusionCompute虚拟机发放与管理全链路实战指南

1. 从零理解 FusionCompute 虚拟机发放&#xff1a;为什么它值得你花时间搞透搞虚拟化的朋友大概率都绕不开一个东西——FusionCompute。不管你是刚入行的运维新人&#xff0c;还是已经管着几十台宿主机、几百台虚拟机的老手&#xff0c;虚拟机发放和管理这件事&#xff0c;永远…

作者头像 李华
网站建设 2026/10/18 12:32:11

LeetCode最大矩形:从暴力枚举到单调栈的完整解法

我整理 LeetCode 刷题记录时&#xff0c;经常会把那些“第一眼觉得是中等题、写起来全是坑”的题目单独挑出来重刷。最大矩形就是特别典型的一道&#xff0c;它在很多公司的算法面试里出现频率不低&#xff0c;解法路径又很清晰&#xff1a;表面是二维图形题&#xff0c;内核却…

作者头像 李华
网站建设 2026/10/18 5:06:20

高校AI求职系统使用指南:简历诊断与模拟面试实战

1. 从一份校内指南说起&#xff1a;AI求职系统到底能帮学生做什么每年到了招聘季&#xff0c;高校就业指导中心的老师都会面临同一个困境&#xff1a;学生数量多、求职问题杂、个性化辅导需求大&#xff0c;但真正能坐下来一对一改简历、模拟面试的老师就那么几位。我接触过不少…

作者头像 李华
网站建设 2026/10/21 20:20:48

环境科学与工程考研专业课资料全解析

1. 考研资料的价值与定位备考环境科学与工程专业研究生入学考试&#xff0c;专业课资料的质量直接决定了复习效率和最终成绩。作为中国海洋大学环境学科的核心初试科目&#xff0c;838专业课涵盖环境科学基础、环境工程原理、环境化学等核心内容&#xff0c;其考察范围广、知识…

作者头像 李华
网站建设 2026/10/22 9:19:13

Delphi中用TPaintBox生成显示二维码,并保存为PNG回读Image的完整实践

1. 从画布到文件&#xff1a;为什么用PaintBox而不是直接放Image最近在做桌面端工具时&#xff0c;遇到一个挺典型的交互需求&#xff1a;界面某处要根据数据动态生成二维码&#xff0c;当场显示给用户看&#xff0c;同时提供一个“保存图片”的按钮&#xff0c;把二维码落盘。…

作者头像 李华