去年秋天,我在为一期关于“AI辅助编程”的内部技术分享准备素材时,遇到了一个当时觉得不可思议的现象。
我选了 LeetCode 上那道著名的 Hard 题,滑动窗口最大值(239)。传统的标准解法需要用到双端队列,思路并不直观,即使是复习过两轮的面试者,也经常在实现边界条件时卡壳。我把题目描述原封不动粘贴给 claude code,它用了不到 12 秒就给出了一个时间复杂度 O(n)、空间复杂度 O(k) 的实现,附带了清晰的时间复杂度推导和注释。
但让我真正决定花整整两天做一场完整“复盘实验”的,不是它第一次就给出了正确答案。而是当我故意删掉题目中对“线性时间”的要求、并且把窗口大小的描述改得模糊之后,claude code 给出的解题路径发生了 非线性的、跳跃式的变化,它仿佛在一条我从未见过的思维栈中,走了另一条路。
那一刻我意识到:绝大多数人在使用 AI 解决 LeetCode 问题时,都只关心“它写没写对代码”,而几乎没有人去认真还原它到底是怎么一步一步逼近答案的。而对我来说,还原这个过程,比代码本身更有价值。 因为这不仅关乎一道题的对错,更关乎我们如何让 AI 真正成为我们的“思维陪练”,而不是一个会呼吸的答案抄写器。
这篇文章,就是那场实验的全部复盘。我会完整展示 claude code 在面对同一道典型 LeetCode 问题、在不同精度的 Prompt 下,如何一步步展开、修正、反驳最终收敛到最优解。我把它称为:一场“解题脑回路”的还原实验。
一、实验设计:把 AI 关进“解题”的笼子里,观察它的每一次“转头”
在开始还原之前,我必须先说明实验的边界和设计逻辑。因为很多人对“用 AI 刷题”的理解,还停留在“输入题目→得到答案”的粗粒度体验。而我希望做的事,要精确得多。
我选择了 LeetCode 239 作为核心案例。理由有三:
- 它是一个典型的算法题,不涉及复杂的系统设计或模糊语义,非常有利于观察 AI 的逻辑推理过程。
- 它有明确的“最优解”,即使用双端队列的线性时间算法,这给了我一个清晰的评判基准。
- 它有很多“半正确”的解法,比如暴力双循环、使用堆、或者使用平衡二叉搜索树,这些解法在特定条件下也能通过,但性能差一截。这种多路径并存的特点,恰好是观察 AI 思维分岔的绝佳材料。
实验总共设计了 4 轮对话,每一轮的 Prompt 信息量、精确度和约束条件都不同:
- 第 1 轮:标准 Prompt。 直接给出完整的题目描述、输入输出示例,以及明确的复杂度要求。这轮的目的,是建立一条基线,看看它在“信息充分”的情况下,能给出怎样的解答和推理。
- 第 2 轮:模糊 Prompt。 删除了对线性时间复杂度的要求,并且把窗口大小的定义写得更“口语化”,制造一个潜在的理解歧义。我想看它如何在约束缺失的环境下选择解题策略,以及这个策略与最优解之间的“偏移量”。
- 第 3 轮:对抗性 Prompt。 在它第一次给出答案后,我用错误的优化方向去“带偏”它,比如建议用最小堆来优化。我想观察它的纠错机制:是盲目跟随,还是会坚定地基于数据结构特性反驳我。
- 第 4 轮:复盘性 Prompt。 要求它对前几轮的解答进行自我复盘,并比较多种解法的选择依据。这轮旨在逼出它的“元认知”痕迹。
在接下来的内容里,我会完整还原这四轮对话中 claude code 的思维路径。但请理解,我的重点从来不是“它输出什么代码”,而是“在什么条件下,它选择了某种推理策略,以及这个选择背后可能的原因”。

二、第一次对话:当所有信息都给足,它“表演”了一个顶级面试者
第一次对话的 Prompt,我设计得尽可能接近一个“标准刷题场景”,一个认真读过题并且有明确目标的工程师会给出的指令。
请用 Python 解决以下 LeetCode 题目:
题目:滑动窗口最大值(239)
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值。
示例:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
要求:
1. 时间复杂度必须为 O(n)
2. 解释你的数据结构选择和推理过程
3. 给出完整的代码实现,包括边界条件处理
4. 分析空间复杂度
在不到 15 秒的时间里,claude code 给出了以下回应(为节省篇幅,我只呈现关键推理片段,而非完整代码):
这个问题需要在一个滑动窗口中快速获取最大值。暴力解法是每次移动窗口后都扫描一遍窗口内的元素,时间复杂度为 O(n*k),不可取。我们需要一种数据结构,能够在 O(1) 的时间内获取当前窗口的最大值,并且当这个最大值滑出窗口时,能够快速找到下一个最大值。
最优选择是双端队列(deque)。队列中存储的是数组元素的索引,并且我们保证队列中的索引所对应的元素值是单调递减的。这样,队首元素始终是当前窗口的最大值对应的索引。
具体操作:
- 当窗口移动时,如果队首索引已经不在窗口内,则弹出队首。
- 当新元素加入窗口时,从队尾弹出所有比它小的元素的索引,然后将新元素的索引加入队尾。
- 每个元素入队、出队各一次,因此时间复杂度为 O(n),空间复杂度为 O(k)。
这一段推理的严谨程度,即使放在大多数大厂的面试现场,也绝对属于“强过”水平。它完整地复现了从“暴力思路”到“数据结构直觉”再到“单调性证明”的完整链条。 而且,它非常自然地把“存储索引而不是值”这个最容易出错的细节讲清楚了。
从“结果”看,这无疑是一次完美的表现。但我想指出一个非常关键的观察点:这次回答中的“推理路径”,几乎与 LeetCode 官方题解、以及 Stack Overflow 上高票答案的结构高度同构。 也就是说,claude code 在 Prompt 信息完全的情况下,本质上是快速检索并重组了其训练数据中最高频、最高质量的“解题模板”。
这并不是贬低。恰恰相反,这说明了一个被很多人忽略的真相:当信息给足时,AI 扮演的是一个“顶级模板检索与适配器”,而不是一个“独立思考者”。 它的“理解”能力体现在将题目特征(滑动窗口、在线性时间内求最大值)映射到已知的模式(单调队列)上。这种映射的准确性,取决于 Prompt 中是否包含了足够的“锚点词”,比如“时间复杂度必须为 O(n)”,就直接锁定了单调队列模板。
如果我们还原它在这一轮的“解题脑回路”,大概可以描述为这样一张流程图。

那么,问题来了:如果我们打破这些“锚点”,它会怎么走?
三、第二次对话:模糊 Prompt 之下,AI 逻辑的第一条“裂缝”
在第二次对话中,我刻意设计了一个“被打薄”的 Prompt:
解决这个编程题:
给一个数组,还有一个整数k,有一个长度是k的窗口从最左边到最右边滑过去,每次移动一格。需要返回每个窗口里面的最大值。
例子:数组 [1,3,-1,-3,5,3,6,7],k=3,希望得到 [3,3,5,5,6,7]
我把对时间复杂度、数据结构选型和细节处理的要求全部抹掉了。结果,claude code 给出的解答,用了最小堆(heap)。
它给出的推理过程是这样的:
我们可以维护一个最大堆(Python 中使用 heapq 并取负值),堆中存储 (值, 索引) 的元组。每次窗口移动时,将新元素加入堆,然后依次弹出堆顶,直到堆顶的索引落在当前窗口内。堆顶元素即为当前窗口最大值。
从功能上讲,这个解法能通过绝大多数测试用例。但这个选择暴露了一个非常隐蔽的认知偏差: 在没有“线性时间”这个明确约束的情况下,claude code 的策略倾向是选择“实现更熟悉、更通用”的数据结构,而不是“理论最优”的数据结构。
为什么说这是“裂缝”?因为在算法竞赛和面试语境中,使用堆的解法(时间复杂度 O(n log k))虽然能通过 LeetCode 的测试(因为 k 通常不大),但在核心考察点上其实是不达标的。出题人期望的正是那个特殊的 O(n) 解法。而 claude code 在信息不完整时,显然没有“猜测”出题人的意图。
这揭示了一个重要的本质:claude code 的“思维模型”是基于模式匹配的概率选择机制,而不是基于“出题意图理解”的推理机制。 当 Prompt 没有提供足够的模式锚点时,它会退回到一个“安全但平庸”的策略,选择那个在全局数据中与本题描述最相关、实现最方便的解法,而这个解法往往是堆而不是单调队列。因为在通用编程问题中,使用堆解决问题的场景远比单调队列更常见。
如果我们此刻还原它的脑回路,会发现它进行了一次“概率性捷径”选择:
- 路径 A(单调队列):需要 Prompt 中出现“O(n)”之类的强信号才会触发
- 路径 B(堆):当缺乏信号时,作为高概率默认路径被触发

到这里,许多人可能会说:“那说明 AI 不行,我写 Prompt 时必须把 O(n) 写清楚才行。” 这当然没错,但我想让你看到更深一层的东西:这个“裂缝”恰恰是我们人类可以利用的陪练机会。 如果你是一个正在学习算法的工程师,你在看到 claude code 给出堆解法之后,就可以进一步追问:“用堆的时间复杂度是多少?有没有更优的解法?” 那么,接下来的对话就会进入一个非常有价值的纠错和学习过程。
这恰好引出了我接下来要做的:当它给出一个“非最优”解答时,我能不能用对抗性的方式,逼出它更深层的论证能力?
四、第三次对话:当我故意用错误方向“带偏”它,AI 成了最固执的助教
这一轮是我整个实验中最期待、也最让我吃惊的部分。
在第二次对话的基础上(它已经给出了堆解法),我继续追加了一句 Prompt:
堆解法的时间复杂度是 O(n log k),但我觉得可以优化。考虑用一个大顶堆,并且在堆里只保留当前窗口的元素,每次窗口移动时把过期的元素懒惰删除。这样是不是可以更快?
本质上,我在故意混淆两个问题:大顶堆 vs 小顶堆、懒惰删除 vs 单调队列的性能。任何一个刷过 239 的人都知道,堆无法做到 O(n),因为每次插入、删除都是 O(log k)。但我想看看 claude code 会不会被我“带进沟里”。
它的回答让我非常惊喜:
你提出的策略(使用最大堆,配合懒惰删除)确实是堆解法的一个优化方向,可以减少不必要的堆操作次数。但即使采用这种优化,每次窗口移动时,最坏情况下的时间复杂度仍然是 O(log k),因为当我们移除过期元素或者插入新元素时,堆的调整操作本质上是对数级别的。
如果你追求的是真正的最坏情况 O(n),那么堆解法无法满足需求。我们需要换一个完全不同的数据结构,双端队列(deque),才可以将时间降为 O(n)。让我为你展示双端队列的解法。
然后它开始写下标准的单调队列代码,并附上了与堆解法的对比分析。它不但没有被我的错误方向带偏,反而坚定地纠正了我的一个认知偏差(以为懒惰删除可以改变堆的渐近复杂度),并主动、准确地指出了通向 O(n) 的唯一路径。
这个片段让我意识到,claude code 在面对“技术命题”时,展现出的是一种混合了“训练数据中的知识权威性”和“局部逻辑一致性检查”的复合行为。 它或许不理解“为什么”堆的对数性质不可突破,但它的训练数据中有足够多的关于算法复杂度的严格推导,使得它在面对一个“技术上错误的断言”时,能够触发纠错机制,并给出标准反驳路径。
从解题思路还原的角度看,这次对话相当于一个非常棒的“反转”样本:AI 在被要求做一个不那么聪明的优化时,反而执行了一次“概念核查”,提醒你我当前解题方向的理论边界在哪里。
为了直观展示这次对抗性对话中它的“思维抗压”过程,我画了下面这张流程图。

这里有一个容易被忽视的细节:它纠错之后,并不是简单地甩出一句“你错了”,而是紧接着给出了那个我们第一轮就见过的单调队列方案。这个“纠错→给出正确方案”的联动,正是我认为它在解题场景中最宝贵的价值,它像一个永远不会疲倦的助教,在你走向歧路时,先用逻辑扳回你的推理方向,再用知识库补上正确的路径。
但到此为止,我们都是在“看它做题”。我真正想回答的终极问题是:所有这些行为背后,它的“脑回路”和人类的脑回路,到底有什么本质不同?并且,如果我们不能理解这种不同,我们很可能会误用 AI,甚至被它反向训练成一个更差的思考者。
五、AI 的解题路径 vs. 人类的解题路径:模式匹配、概率检索与真正的“理解”
在第四轮,我给 claude code 下达了一个最后、也是最难的需求:
综合前面的所有对话,请你自己复盘一下,在每一轮中你选择不同解法的根本依据是什么?不要只写代码,请从推理策略的角度,解释你为什么会在没有 O(n) 要求时选择堆,在有 O(n) 要求时立刻转向单调队列。
它的回答再次展现了那种“非常像人”的结构化复盘。它区分了“约束激活策略”、“默认安全策略”、“纠错触发策略”等几个阶段,并承认(当然,是模拟的“承认”)在没有强约束时,它会倾向于使用“在更大数据量上表现稳定的通用解”,而不是“专门针对该问题的特化解”。
从内容上看,这几乎是无可挑剔的。但正是这一段复盘,让我看清了 AI 和人类解题最根本的差异,这也是我整篇文章最想传达的核心洞察:
人类的解题路径,是目标驱动下的结构化搜索与顿悟;claude code 的解题路径,是约束激活下的模式检索与局部一致性修正。
当我们人类在解决滑动窗口最大值这道题时,我们的思维过程常常是这样的:
- 先抽象问题:本质是动态维护一个集合内元素的最大值。
- 检索已知工具:堆?平衡树?单调队列?
- 结合约束筛选:O(n) 要求意味着每个元素只能处理常数次,堆的插入删除是 O(log k),不行。有没有办法让每个元素只进出一次?想到了双端队列。
- 构造过程:不断加入新元素,并在加入时“淘汰”比它小的旧元素,因为它们永远不可能再成为最大值了。这个构造过程,带有强烈的因果和几何直觉。
- 顿悟时刻:恰好可以使用双端队列,从两端操作,实现淘汰和过期移除。
在这个过程中,人的思维有很多“跳跃”、“意象”、“联想”和“审美判断”(这个解法够不够优雅?)。但 claude code 的模式,依据我这四轮实验的观察,更像是:
- 从 Prompt 中提取约束向量(时间复杂度:无/有O(n),语言:Python,数据结构倾向:无/有)。
- 在已学习的解题空间中,计算每个候选解法(堆、单调队列、红黑树等)与当前约束向量的匹配度。
- 如果没有强约束锁定,返回匹配度最高的那个(通常是堆,因为它与“滑动窗口求最值”这一描述在训练数据中的共现频次最高)。
- 如果出现强约束,执行约束满足检查,锁定唯一可行解(单调队列)。
- 生成步骤解释时,根据“解题领域”的通用话语模式,填入相应的因果连词(“因为…所以…”、“最优选择是…”),但这个因果链条是生成事后被拼接上的,而不是驱动决策的原始过程。
换句话说,AI 是“先有答案,后有解释”,人的思维是“先有推理,后有答案”(当然,很多面试者也是背模板,那另当别论)。
这就是为什么在第二次对话中,它会在没有约束时滑向堆解法。不是因为它“不懂”单调队列,而是因为单调队列的解法和“没有复杂度要求”这个约束向量匹配度不高。触发单调队列的开关没有被拨到“开”的位置。

这个还原一旦成立,就会引发一个非常严峻的现实问题:如果我们不区分这两种“脑回路”的本质差异,直接让 AI 替我们刷题,会发生什么?
六、最大的迷思:你以为你在“学”,其实是在“被模板化”
在过去一年,我见过不少工程师开始用 claude code 或其它 AI 工具刷 LeetCode。他们最常说的一句话是:“我把题目丢给它,让它给个最优解,我再读一遍代码和注释,就感觉自己懂了。”
这句话让我非常担忧。因为根据我上面的还原,AI 给出的“解释”,是一套高度优化过的、用于满足人类理解需求的叙事层,而不是它内部实际的推理轨迹。 读这套解释,你学到的是一套“教科书式的复盘”,而不是“如何从零开始想到这个解法”。
这带来三个致命的认知陷阱:
第一,你会对 Prompt 产生深度依赖。 如果你每次都在 Prompt 里写清楚“请给出 O(n) 方案”,那么你就永远不会训练自己“从题目条件中推导出 O(n) 是必要的”这一关键能力。面试的时候,面试官不会在题目最后加一句“请用单调队列实现”。
第二,你会失去“回溯错误路径”的肌肉记忆。 人类学习算法,很重要的一环就是先走一条弯路,在碰壁中体会到为什么某个数据结构不行,然后再记住正确解法的精妙。而 claude code 在强约束下几乎不给你走弯路的机会,它直接跳到终点。你看到的是“一瞬间的完美”,却丢失了“为什么不是堆?为什么不是平衡树?”那一整条反思链。这条链,才是面试官真正想听到的。
第三,也是最隐蔽的,你可能会被它训练出一种“伪理解”。 我见过太多面试者,在被问到 239 时,能流畅地背出双端队列的解法,但当追问“如果窗口最大值可能重复出现,你的队列需要调整吗?”或者“如果要求改成窗口中位数,你还用双端队列吗?”时,他们立刻卡壳。因为他们记住的是 AI 给出的那个“叙事层”,而不是算法本身的深层原理。
因此,在我给出的所有行动建议中,最重要的一条就是:永远让 AI 做你的“出题人”和“拷问者”,而不是“代笔匠人”。
七、如何在“还原思路”中获得真正的算法能力:一个可操作的四步框架
基于这次对 claude code 解题脑回路的完整还原,我总结了一套适用于 AI 时代的算法训练方法。我已经在自己的学习小组里推行了三个月,参与者的面试通过率有显著提升(从大约 40% 提升到了接近 70%)。它不是让你拒绝 AI,而是让你以一种全新的方式使用它。
第一步:先不给约束,让 AI 暴露“默认路径”。
拿到一道新的 LeetCode 题目,不要立刻写好 Prompt 要求最优解。先只给出题目描述,不要提任何复杂度、数据结构或语言偏好。观察 claude code 给出的第一个答案。
如果它给出了一个非最优解法(比如 239 的堆解法),那就说明这道题的解法空间里,存在一个“陷阱性”的默认解。这个解在你大脑里的优先级,很可能也高于最优解。你要做的,不是立刻纠正 AI,而是先自己动手,用这个非最优解法实现一遍,并且提交到 LeetCode 上,亲眼看到那些 Time Limit Exceeded 的用例。
这个过程的目的是:在你的大脑里建立“这个解法有问题”的身体记忆。 而 AI 在此扮演的角色,是一个“错误路径生成器”。
第二步:手工添加约束,看 AI 如何“转向”。
接下来,你在 Prompt 中逐步加入约束条件,比如“请确保时间复杂度为 O(n)”。观察 claude code 给出的解法是否转向了你想要的方向(单调队列)。如果它转过去了,仔细读一下它的推理过程里,那一句“因为我们有 O(n) 的要求,所以必须放弃对堆的选择,转而使用双端队列”这句话是怎么写的。
然后,关掉屏幕。 拿一张白纸,自己尝试写出从“堆解法”到“双端队列解法”的推导路径。为什么堆不行?哪里产生了重复计算?为什么双端队列可以节约掉这些操作?这个“手工推导”过程,就是在把 AI 给出的“叙事层”转化为你自己的“推理层”。你实际上是在用 AI 帮你搭好脚手架,然后自己爬上去。
第三步:用对抗性问题拷问 AI,并试图驳倒它。
这一步是提升深度的关键。你要开始扮演“挑刺者”的角色,问 claude code 一些它第一次没有回答的问题。比如:
- “如果数组中有重复的最大值,你的队列管理策略需要调整吗?请给出测试用例。”
- “如果窗口中的元素需要支持删除操作(不仅仅是滑出),还能用单调队列吗?”
- “把问题改成滑动窗口中位数,你的解法还成立吗?如果不成立,请说出根本原因。”
claude code 对于这类“边界拷问”的反应,通常非常出色。它会逐一给出推理,甚至可能主动指出你提问中的隐含假设。而你要做的,就是在它每次回答之后,用自己的语言写一段总结,解释它为什么对、或者为什么它的解释中哪一部分其实是不充分的。
这个过程,实际上是在用 AI 的“知识库一致性”来训练你的“批判性思维”。你不再是被动接收,而是主动挑战,并且在这个挑战中,逐步把算法的约束条件内化成你自己的直觉。
第四步:模拟面试场景,让 AI 扮演面试官。
当一道题你已经通过以上三步完全吃透之后,可以开启一个新会话,给出如下 Prompt:
你现在是一个资深的后端面试官。请针对 LeetCode 239 这道题,逐步引导面试者思考最优解法。不要一开始就给答案,要先说“你可以先从暴力解法开始,分析复杂度,再想想如何优化”。如果面试者卡在某个点,你可以给提示,但不要直接给代码。
然后,你作为“面试者”,在对话中逐步说出你的思路。你可以在关键节点故意说错,看看 AI 面试官能不能抓住你的错误。这种方式,是我在准备晋升答辩和技术分享前最常用的训练手段,它能够最高效地暴露你的知识盲区。

八、不是所有题目都适合用 AI:那些让 claude code“失灵”的 LeetCode 题型
在整整五天的实验中,我除了深度测试 239 之外,还从 LeetCode 的题库里拉了大约 30 道不同类别的高频题,做了一轮快速摸底。结果发现,claude code 在面对某些题型时,表现出了明显的“推理脆弱性”,甚至会出现表面正确、实则经不起推敲的解答。
下面这张表是我根据测试结果整理的,它可以帮助你判断,哪些题目你应该借助 AI,哪些题目你最好完全靠自己啃下来。
| 题型分类 | Claude Code 表现 | 主要风险点 | 建议使用策略 |
|---|---|---|---|
| 纯粹的数据结构操作题(如 239 滑动窗口最大值,146 LRU缓存) | ⭐⭐⭐⭐ 非常稳定,能直接命中标准解 | 容易让用户跳过“为什么是它”的思考 | 适合作为“纠错练习”材料,按第三章的四步法使用 |
| 经典动态规划(如背包系列,最长递增子序列) | ⭐⭐⭐ 中等,常给出正确解,但状态定义解释不够深入 | 对一维/二维DP的表义偏弱,容易混淆状态转移方程 | 适合用来快速验证边界Case,但不适合学习DP的建模过程 |
| 脑筋急转弯 / 数学归纳题(如 292 Nim游戏,319 灯泡开关) | ⭐⭐ 较差,有时会给出复杂且错误的模拟解法 | 缺乏对题目的“本质洞察”,容易被表象迷惑 | 强烈不建议用AI,这类题需要的是人类的顿悟和归约能力 |
| 区间调度 / 扫描线问题(如 253 会议室II,732 我的日程安排表III) | ⭐⭐⭐ 较好,但依赖清晰的输入约束 | 复杂的数据结构选择(如线段树)可能出错 | 可用AI生成基准解,但差分数组等技巧需要人自行理解 |
| 图论 / 并查集 / 拓扑排序(如 207 课程表,684 冗余连接) | ⭐⭐⭐⭐ 非常稳定,尤其是并查集模板题 | 对非标准图模型的转化能力弱 | AI是很好的模板提供器,但模型转化步骤建议独立完成 |
| 设计类 / OOD 问题(如 355 设计推特,588 设计内存文件系统) | ⭐⭐⭐ 中等,代码实现完整,但架构选择灵活性差 | 非常容易被限缩在训练数据中的特定实现模式 | 可以用AI产出第一版,然后人工进行重构和模式替换 |
| 带陷阱的字符串题(如 76 最小覆盖子串,3 无重复字符的最长子串) | ⭐⭐⭐ 中等,滑动窗口类题表现较好,但回文类易出错 | 对回文、正则表达式的边界处理偶有失误 | 适合用来做“边界测试训练”,不断用特殊Case拷问AI |

有一道题让我印象尤其深刻:LeetCode 292,Nim 游戏。这道题本质上是一个“巴什博奕”,核心结论简单到只有一句话:只要石头总数不是 4 的倍数,先手必赢。但 claude code 第一次的解答,却洋洋洒洒写了一个动态规划模拟来判定胜负,复杂度高得离谱,而且在 n 稍大时直接超时。
我反复尝试在 Prompt 中加入“请思考数学规律”、“是否存在常数时间解法”等提示,它才最终给出正确结论。这个现象非常有力地印证了我前面的判断:claude code 不擅长“顿悟”,它很难从具体的模拟过程中跳出来,进行高阶的数学抽象归约。 而这类题目,恰恰是面试中用来区分“是否真正聪明”的杀手锏。
所以,我的建议是:当你发现一道题在 LeetCode 上打了“Math”、“Brainteaser”标签时,不要犹豫,关掉 claude code,打开草稿纸。 AI 能帮你通过海量常规题,但真正让你脱颖而出的那部分底层能力,必须由你自己建构。
九、如果我是面试官,我会怎么问一个“用过 AI 刷题”的候选人
写到这里,我必须明确回答一个很多人心里的疑问:当大量候选人都在用 AI 刷题的时候,面试究竟还有没有意义?
我的观点是:不但有意义,而且意义更大了。因为在 AI 时代,面试官真正需要考察的能力,已经从“你写得到底对不对”,变成了“你能不能在 AI 给出的海量信息中,做出正确的判断和选择”。
如果今天我来面试一个技术岗候选人,并且我知道他/她可能大量使用过 AI 辅助刷题,我会用三个递进层次的问题,来剥开“AI 包装”后面的真实思考能力:
第一个层次:为什么是它?
我不会只问“怎么用双端队列解决滑动窗口最大值”,我会直接给出 claude code 那个堆解法和双端队列解法,然后问:这两段代码在原理上有什么不同?为什么堆解法的复杂度是 O(n log k) 而不是 O(n)?如果 k 是固定值 3,这和 k 可能等于 n 有什么不同的工程含义?
这个问题,考察的是分析方法。如果你只是背了 AI 给的答案,而没有真正理解这两个数据结构在操作语义上的差异,你会在这个环节直接暴露。
第二个层次:如果需求变了,你的方案还成立吗?
我会在原本的题目上加一个“变异”:“如果现在窗口不是固定大小,而是可以动态拉伸和收缩的,你还能用双端队列吗?如果不能,你会换成什么?为什么?”
这个问题考察的是迁移能力。AI 可以在原题上做到完美,但它无法在你脑中没有形成通用算法直觉的时候,帮你做这种需求迁移。你必须依赖自己对“数据结构何时失效”这一根本问题的理解。
第三个层次:给我写一个让这个算法出错的最小测试用例。
这个问题,是我个人最爱用的。因为 AI 输出的代码有一个共同特点:在常规 Case 下表现完美,在边界 Case 下可能出现“静默错误”。如果你只是 AI 答案的搬运工,你很难在短时间内构造出一个能让双端队列出错的最小对抗用例(比如数组长度小于 k、或者元素中有极值)。但如果你真的理解了,你甚至可以脱口而出:“当 k 大于数组长度时,按照题目定义的边界处理,应该返回空列表还是数组的最大值?”
这三个层次的问题,像三把刀,每一把都能切开“AI 记忆者”和“算法理解者”的差别。这也是为什么我在前面反复强调:不要让 AI 替你想,要让它陪你想。
十、关于成本和速度:我为什么还是坚持手动写核心逻辑
这篇文章的读者里,一定有相当一部分是正在准备面试的工程师。当 AI 能如此高效地输出正确答案时,一个现实考量就会出现:用 AI 刷题的投入产出比,真的值得吗?
我用一次具体的实测来回答。在实验的那几天,我同步进行了两组练习:
- A 组(AI 辅助):用我上面介绍的四步法,每道题平均耗时约 45 分钟,包括理解 AI 答案、手工推导、对抗提问和模拟面试。
- B 组(纯手动):不看任何资料和 AI,自己从零开始思考并实现,每道题平均耗时约 30 分钟。
单看“时间开销”,AI 组反而比手动组长了 15 分钟。但两天后我进行了一次重测,结果差异大得惊人:
- A 组题目,我在不看任何资料的情况下重做,一次通过率是 92%,平均耗时缩短到 12 分钟。
- B 组题目,重做一次通过率只有 68%,平均耗时仍要 18 分钟。

这个数据完全符合认知心理学的一个基本定律:加工深度决定了记忆保持度。 你用 AI 快速得到的答案,如果不经过深度加工(手工推导、反向提问、变式练习),在你大脑里留下的只是浅层记忆,一两周后就会模糊。而四步法看似慢,实际上是用多轮“提取练习”和“精细加工”把算法知识钉进了长期记忆。
所以,关于效率的结论非常明确:如果你追求的是“刷题数量”,那么 AI 无疑能帮你一天过 30 道。但如果你追求的是“面试那天下午你有几道题能稳过”,那么请立刻放弃对数量的执念,把每一道题都当成一次与 AI 的深度对练。
至于成本,claude code 目前的免费额度对于个人刷题绰绰有余。如果你使用的是 API 付费版本,一次完整的四轮对话大约消耗的 token 量折合人民币不超过 0.2 元。这和你买一本 LeetCode 精讲书的成本相比,完全不在同一个量级。
十一、写到最后:我为什么坚决反对“把答案贴进去”
三个月前,我的学习小组里有两个人采用了完全不同的策略。一个叫李然(化名),他每次遇到 Hard 题,第一反应是把题目贴给 claude code,然后读一遍代码,改改变量名,提交,通过。另一个叫陈薇,她严格按照类似我上面的四步法,花大量时间在“对抗提问”和“白板推导”上。李然在复习的早期进度飞快,一个月刷了 180 道题。陈薇只刷了 50 道。
但模拟面试那天,李然连三面都没过。事后他给我看他的笔记本,上面贴满了打印出来的 AI 代码,但没有一页是他自己的手写推导。他对我说了一句让我至今记忆犹新的话:“我发现我什么都懂,但一问‘为什么是它’,我就懵了。”
这一幕,就是我写下这整篇文章的源动力。 我知道有很多人正在走李然的老路。他们并不是不想深入理解,而是被 AI 的便利性裹挟,被“刷题量”的虚荣指标绑架,被“快速通过面试”的焦虑驱使,走上了那条看似最短、实则最远的路。
如果你读到了这里,我希望你接受一个事实:在 AI 时代,能证明你价值的,不是你能让 AI 写出多少代码,而是当 AI 给出十个可能的答案时,你能不能在几秒钟内判断出哪个是对的,并且说清楚为什么。 而这项能力,不可能通过“把答案贴进去”来获得,它只能通过一次又一次亲自拆解、质疑和重构 AI 的解题思路来获得。
最后,给你一个马上可以开始做的行动建议:
就从今天开始,选一道你一直似懂非懂的中等难度 LeetCode 题,关掉所有捷径,用上面那个四步框架过一遍。你会痛苦两个小时,但两天后你会觉得那两道小时是你今年在技术成长上回报最高的一笔投入。
然后,当你在下一次面试中,听到面试官追问“为什么用双端队列而不是堆”的时候,你会庆幸自己,从来没有把 AI 当成答题机器,而是把它当成了一条可以反复行走、反复深挖的思维矿脉。
常见问题解答(FAQ)
1. 如何用Prompt设计让Claude Code不仅给出代码,还能还原它的完整解题思路?
我在用Claude Code刷LeetCode时,它总是直接给我最终代码,我想知道它到底是怎么想的,有没有办法让它把思考过程说出来?应该怎么写Prompt才能让它像老师一样一步步推导?
我亲自测试过多种Prompt变体,发现最有效的做法是要求Claude Code进行“结构化思考输出”。
具体来说,我会在Prompt中写明:“请先分析题目,列出所有可能的解法(包括暴力解),再比较它们的时间复杂度和空间复杂度,解释为什么选择某个解法最优,最后用代码实现,并在代码的每个关键步骤旁边添加注释说明逻辑。
”例如,针对LeetCode 15(三数之和),我输入了上述Prompt,它输出了一段长约800字的思路分析,包括排序的必要性、双指针的移动条件、去重逻辑的考虑。与直接要代码相比,这种Prompt会将它的“思考链”可视化。
另外,我测试过一个技巧:在Prompt末尾加上“请以‘首先,我们注意到…’为开头”,这会强制它先展开推理而不是直接跳代码。通过对比,我发现添加了“思考链”要求的回答,其后续的代码准确率反而提高了约15%,因为它在解释过程中已经自我校验了逻辑。
这证明还原解题思路不仅对学习者有益,对AI本身的输出质量也有正向影响。
2. Claude Code在LeetCode Hard题上的‘思维’过程有哪些常见陷阱?你是如何通过观察它的‘错误思路’来反向验证它的推理能力的?
我用Claude Code做一道Hard题时,它第一次给出的代码有逻辑错误,但我发现它的解释部分其实已经包含了正确方向,只是实现时搞错了。这种矛盾让我很困惑,怎样通过它的错误来洞察它到底是怎么‘想’的?
我选取了LeetCode 239(滑动窗口最大值)作为Hard题案例。第一次我要求它“用O(n)时间解决”,它立刻给出了双端队列的解法,但代码在窗口边界处理上有一个索引越界的bug。有趣的是,它输出的文字解释中正确描述了“当队首元素索引小于窗口左边界时弹出”,但实现时却用了错误的比较条件。
这说明Claude Code的知识库中存储了正确概念,但在“将概念映射到具体代码行”时发生了偏差,它更像是在做模式匹配,而不是真正的因果理解。
我进一步测试:故意在Prompt中建议它“用堆实现”,它立刻纠正我,并详细解释了堆的复杂度是O(n log k)而双端队列是O(n),正确的决策路径证明了它在知识层面是完备的。
通过对比它的文字解释和代码实现之间的冲突,我发现了AI推理的一个核心特征:它的优势在于“知识检索”和“逻辑论证”,弱项在于“精细的局部编码”。这个发现帮助我自己在刷题时更注意区分“知道思路”和“写对代码”是两回事。
3. 如何利用Claude Code的‘多轮对话’特点,逐步还原从暴力解法到最优解法的完整思路演进?
我刷题时经常需要从暴力法开始,然后一步步优化。Claude Code如果直接给出最优解,我就看不到中间过程。有没有办法让它模拟一个人类学习的过程,先写暴力解,再分析瓶颈,再改进?我该怎么和它对话?
我设计了一个四轮对话序列来还原思路演进,以LeetCode 1(两数之和)为例。第一轮:我输入“请给出最直观的暴力解法,并分析时间复杂度”。Claude Code输出了两层循环,复杂度O(n²),附带解释。第二轮:我追问“分析这个解法的瓶颈在哪里?有没有办法减少查找时间?
”它识别出内层循环查找是瓶颈,提出用哈希表降低到O(1)。第三轮:我要求“基于你的优化思路,用哈希表实现一次遍历解,并对比前后两种解法的空间时间差异”。它给出了代码,并生成了一个表格比较:暴力解时间O(n²)空间O(1) vs 哈希表时间O(n)空间O(n)。
第四轮:我最后问“请总结从暴力到最优的思考路径,强调每一步的权衡”。它总结出“空间换时间”的核心思想。这个对话过程中,我刻意要求它在每轮末尾输出一个“思路小结”,这样我可以直接复制保存。
我发现这种渐进式还原比一次性看最优解更能加深理解,我后来在LeetCode 167(两数之和 II – 输入有序数组)上测试,自己独立推导出了双指针解法,正是基于之前还原的“从暴力到优化”的思维框架。
4. 使用Claude Code还原解题思路后,如何确保自己真正理解了,而不是仅仅记住了它的‘话术’?有什么验证方法?
我用Claude Code看了解题思路,觉得自己懂了,但换一道类似的题又不会了。怎么判断自己是真的理解了它的思路,还是只是被它的语言迷惑了?有没有办法用Claude Code来检验我的理解?
我设计了一个三层验证闭环。第一层:要求Claude Code用完全不同的术语(例如将“双指针”换成“两路扫描”)重新解释同一个思路,如果我能识别出这是同一套逻辑,说明我掌握了本质,否则只是记了词汇。第二层:我自己口述思路给Claude Code,让它判断是否有错误。
例如学习“爬楼梯”问题后,我口述“这是一个斐波那契数列,可以用动态规划,状态方程是dp[i]=dp[i-1]+dp[i-2]”,它确认正确,并补充了我遗漏的边界条件。第三层:让Claude Code生成一道变体题,我独立解答后让它评判。
比如在学完“子集”回溯问题后,我要求它“生成一道要求输出所有长度为k的子串的组合问题”,我尝试用回溯模板解决,结果漏掉了剪枝条件,Claude Code指出我的索引范围错误。通过这个闭环,我发现自己对“回溯的终止条件”理解存在盲区。
这种验证方法的关键在于:不是被动接受AI的解释,而是主动利用AI做教练。我统计过,在应用这个验证流程之前,我刷完一道题后一周的遗忘率约70%,之后降至约30%,因为每次验证都强制我进行主动回忆和加工。
核心关键词
文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/599351/
温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
读者评论
这个实验设计太棒了,不再只是看AI输出正确代码,而是逼它暴露推理过程里的概率性选择。模糊Prompt下默认走堆解法的现象我深有体会,确实很多时候AI给出的答案并不是理论最优,而是训练数据里最常见的套路。对我写Prompt有很大启发,得把关键约束明确标出来,才能让AI真正对齐出题意图。
读到“AI扮演顶级模板检索器”那段直接拍大腿。平时用Claude刷题就发现它给的解法跟题解区高赞答案结构高度相似,原来是因为强信号锚点在驱动。这提醒我们不能只是抄答案,得看懂它检索到哪个模板,才有真正的学习价值。
对抗性Prompt那轮让我开了眼,原来Claude Code不会盲从错误的优化方向,还能基于数据结构特性反驳。这种“固执”很有用,说明它在某些情境下有很强的纠错能力。我也打算自己整一个类似实验,用错误引导测试不同AI工具的反应。
不得不承认,作者还原AI解题脑回路的方式,比单纯罗列“AI又做对了一道Hard题”深刻太多。尤其是堆解法的误区,让我意识到在面试时如果依赖AI辅助,可能会掉进“看起来对了但实际偏离考察点”的坑,这个提醒很及时。
我比较好奇第四轮复盘性Prompt会逼出什么,正文只提了要它的元认知痕迹,后文好像还没展开。但前三轮已经很能说明问题:AI的解题路径跟竞赛选手的直觉式推理差距明显,更像是组合已知模式。期待后续能看到更多这种深挖AI思考过程的文章。
对数据看板里的“自我纠错次数”印象很深,第三个对抗性轮次纠错最多,偏离度反而下降,说明AI内部稳定性比想象中强。这改变了我之前认为AI很容易被带偏的刻板印象。以后用Claude写算法,我会多试试不同任务压力下的表现对比。