110天吃透LeetCode面试经典150:数据结构与算法刷题路线复盘

发布时间:2026/10/20 16:55:45

110天吃透LeetCode面试经典150:数据结构与算法刷题路线复盘 今天3月11号是我把 LeetCode 面试经典150 作为主刷题单的第110天。100多天前我还在各种题海里乱撞每天刷十来道简单题晚上复盘的时候发现啥也没剩下。后来一个从秋招里杀出来的朋友给我指了条路别贪多把这套覆盖高频考点的经典题单吃透比散着刷两百道更有效。于是从第1天开始我给自己定了个规矩每天至少一题按专题推进周末做一次完整复盘。110天下来这套题单已经过了快两轮很多题目从“看过答案才会写”变成“看完题目就有思路”。这篇文章就是把这段经历里沉淀下来的东西做个整理为什么选这套题单、数据结构类题目怎么系统过、高频算法套路怎么总结、每天的执行节奏怎么设计、以及最容易踩的那些坑怎么排查。不管你是在准备实习、秋招还是想系统性补算法基础应该都能从中找到直接能用的东西。1. 为什么选“面试经典150”1.1 从“题海战术”到“经典题单”的转变我早期刷题有一个很典型的毛病看见什么刷什么简单题一口气刷十几道困难题死磕到凌晨第二天起来记忆清零。后来我发现问题不在刷题数量而在刷题结构。面试里反复出现的高频知识点其实是有限的与其在零散题目里碰运气不如把一套经过筛选的题单吃透。面试经典150最打动我的一个设计是它不是按难度随缘排列的而是按专题展开的。比如数组相关的双指针题归在一起二叉树的各种遍历放一起动态规划从背包到序列问题循序渐进。这种结构意味着你每次动手刷题都在处理同一个技术主题前后题目的解法可以互相印证。今天刷的“合并区间”可以帮明天理解“插入区间”这种关联感是散刷很难获得的。我记得第一阶段刷“数组/字符串”专题的时候连续几天都是类似的操作手法要么是双指针从两端逼近要么是从后往前原地填充要么是哈希表辅助记录。到专题末尾我已经能预判下一题大概要用什么思路了。这种“预判”能力就是专题训练带来的核心收益。1.2 这套题单的真实覆盖面面试不是考试它更看重的是你是不是真的理解了数据结构和算法的本质。经典150里的很多题目与其说是考题不如说是题型母本。面试官经常做的一件事是“换皮”把“两数之和”改成“所有下标对组合”把“反转链表”改成“每隔k个反转一次”。如果原题思路扎实变形题上手就快。覆盖面方面数组、链表、栈、队列、哈希表、二叉树、图、堆基本全都有二分、双指针、滑动窗口、回溯、动态规划、贪心、拓扑排序也全部覆盖。我在实际面试里遇到的高频考点绝大部分都能在这套题单里找到对应原型。它不是让你把所有题背下来而是让你建立一套“看到题目特征就自动匹配数据结构”的能力。1.3 谁适合直接拿它当主力题单如果你完全零基础连数组和链表都分不清那我不建议一上来就刷这套题单。它默认你已经掌握了基本语法和简单逻辑直接从题目倒逼原理效率不会太高挫败感还强。但如果你已经刷过二三十道入门题或者正在准备面试它就是性价比最高的选择。转码选手也可以用它搭配基础教程同步推进白天看一章数据结构理论晚上找对应专题的经典题练手。这样“理论例题”的闭环比单纯啃书或者单纯刷题都靠谱。我见过不少刚开始准备面试的人明明时间不多还在纠结选哪本习题集结果一个月过去什么都没开始。与其纠结不如从这套题单的第1题开始动手。2. 数据结构题型的通关逻辑2.1 数组和字符串先学会原地操作数组这类题看着简单实际是很多技巧的载体。像是“合并两个有序数组”“移动零”“旋转矩阵”表面上是在处理数组本质上考的是你是否理解连续内存结构下的位置替换。以“合并两个有序数组”为例最自然的思路是从前往后逐个比较然后插入但这样需要额外数组或者大量搬移。换个方向思考两个数组本身就是有序的最终结果放在第一个数组里那就从后往前填充每次把两个数组当前尾部较大的元素放到结果尾部。这样只需要一轮遍历就完成合并不需要额外空间。这个思路对很多“原地修改”的题目都适用。提示拿到数组题先问自己三个问题能不能从后往前处理能不能用两个指针同时走能不能先排序再用双指针这三个方向能覆盖大部分数组高频题。2.2 链表画图比硬记模板重要链表题对很多人的痛点在于节点关系一旦变动指针就乱了。我的建议是先学会画图再写代码。拿到一道链表题在草稿纸上画出调整前后的节点连线标注出哪些连接会被覆盖哪些节点需要先保存这比背任何模板都管用。以反转整个链表为例迭代写法本质上就是三个指针的移动ListNode* reverseList(ListNode* head) { ListNode* prev nullptr; ListNode* cur head; while (cur) { ListNode* next cur-next; cur-next prev; prev cur; cur next; } return prev; }关键点在于步骤1先保存next防止在修改cur-next之后找不到后续节点。很多同学第一次写这道题会写成先改指向再找next结果链表当场断掉。链表题还有一个共同点边界条件特别容易漏空链表、单节点、反转后头尾节点的处理都要单独检查。2.3 栈和队列识别应用场景比会用函数更重要栈最经典的场景是括号匹配、表达式求值、逆波兰计算。这类题的共同特征是存在嵌套结构或者需要“最后出现的最先处理”的逻辑。队列则更多用在BFS里按层处理节点。单调栈是栈里面比较容易卡住人的扩展应用。像“每日温度”“接雨水”其实用的是一个“维护栈内单调递减或递增”的思路。我学单调栈的时候踩过一个坑把所有步骤都背下来结果换一道题就不知道怎么弹栈。后来想通了单调栈的核心是“当前元素破坏了单调性时就不断弹出栈顶元素直到重新满足条件”至于弹出的过程中要计算什么取决于题目要什么答案。2.4 二叉树与图遍历是绝对基石树这一块的题百分之七八十都不会脱离三种遍历。递归写起来快但要注意出口条件迭代写起来麻烦点但能帮你理解栈和队列的用武之地。层序遍历是BFS的直接应用代码模板很固定vectorvectorint levelOrder(TreeNode* root) { vectorvectorint res; if (!root) return res; queueTreeNode* q; q.push(root); while (!q.empty()) { int sz q.size(); vectorint level; for (int i 0; i sz; i) { TreeNode* node q.front(); q.pop(); level.push_back(node-val); if (node-left) q.push(node-left); if (node-right) q.push(node-right); } res.push_back(level); } return res; }图比树多了一个visited数组。因为图可能有环不标记访问过的节点就会死循环。像“岛屿数量”这种题本质就是从每个陆地出发做DFS或BFS每找到一个整块岛屿就计数加一。2.5 数据结构选型速查表场景特征优先考虑的结构典型场景频繁头部/尾部插入删除链表、双端队列反转链表、滑动窗口最大值快速按值查找哈希表两数之和、字母异位词分组需要维护区间单调性单调栈 / 单调队列接雨水、最大矩形、滑动窗口嵌套结构配对栈括号匹配、表达式求值层级关系/连通性树、图BFS/DFS二叉树层序、岛屿数量需要快速找最大/最小堆前K个高频元素这张表不是让你背而是当你在题目里看到“找最值”“配对”“区间最值”“连通区域”这些信号词时能快速锁定候选结构。3. 高频算法思维的套路总结3.1 双指针两个指针怎么走决定了复杂度双指针可以分为相向和同向两类。相向双指针常用于有序数组左右指针从两端往中间收找两数之和就是最经典的案例。同向双指针则常见于链表找环、快慢指针。核心价值在于利用数据的有序性把暴力枚举中的无效组合直接跳过。“三数之和”是个很能说明问题的例子。暴力解法是三重循环O(n^3)三层循环嵌套让数据规模稍大就超时。先对数组排序固定第一个数剩下两个数用双指针从两端移动就能把复杂度降到O(n^2)。这类题目做多了你会发现所谓算法优化很多时候就是“能不能省掉一层循环”的问题。3.2 滑动窗口扩大右边界收缩左边界滑动窗口实际上是双指针的一种适合处理子串、子数组这类连续区间问题。核心逻辑不难右指针不断向右扩展窗口直到满足题目条件此时尝试收缩左指针缩小窗口窗口不满足条件了再继续移动右指针。整个过程像窗帘右边拉开左边跟进。模板可以浓缩成四步# 滑动窗口通用框架以寻找最小满足条件的子串为例 left 0 for right in range(n): 加入 right 到窗口状态 while 窗口状态满足条件: 更新答案 移除 left 并从窗口状态中删除 left 1写这个模板时最需要注意的是“窗口状态”的维护。很多同学把更新答案的位置写错或者把条件判断放反。我的建议是每道题先手动走一遍例子把“什么时候算满足、什么时候更新答案、什么时候收缩”理清楚再动笔写代码。3.3 二分查找别依赖模板边界要自己推导二分查找看起来简单但边界条件一换就非常容易出错。我最开始习惯用左闭右闭的写法后来做题发现只要条件变成“寻找左边界”或者“寻找插入位置”就得反复试错。也因此我强烈建议你固定一种写法把它的循环条件、mid更新方式全部吃透。我习惯的左闭右闭写法int search(vectorint nums, int target) { int left 0, right nums.size() - 1; while (left right) { int mid left (right - left) / 2; if (nums[mid] target) return mid; else if (nums[mid] target) left mid 1; else right mid - 1; } return -1; }两个容易踩的坑一是mid (left right) / 2在极端情况下可能溢出写成left (right - left) / 2更安全二是如果用left right作为循环条件退出循环后还要再判断一次当前位置。搜索旋转排序数组这类题本质上是在二分的基础上增加“判断当前区间是否有序”的步骤思路是从有序那一半入手。3.4 动态规划状态定义错了后面全白搭动态规划是很多人的心理阴影但它实际上是有固定工序的定义dp数组的含义、推导转移方程、确定初始值、选择遍历顺序。这四个步骤里第一步“dp是什么”几乎决定了后面所有东西。状态定义清晰了转移方程往往就是一道简单的逻辑题。以“打家劫舍”为例dp[i]表示“偷到第i家时的最大金额”。那么对第i家只有两种选择不偷则金额等于前一家结束时的金额也就是dp[i-1]偷则金额等于第i-2家结束时的金额加上当前价值也就是dp[i-2] nums[i]。于是转移方程int rob(vectorint nums) { int n nums.size(); if (n 0) return 0; if (n 1) return nums[0]; vectorint dp(n); dp[0] nums[0]; dp[1] max(nums[0], nums[1]); for (int i 2; i n; i) { dp[i] max(dp[i-1], dp[i-2] nums[i]); } return dp[n-1]; }这类题目如果卡住了千万别急着看题解。手动把dp表往下推三行推到发现规律为止效果比直接看答案大得多。我大概有三分之一的状态转移方程是推完第三行才突然想明白的。3.5 回溯与贪心一个枚举全部一个只选局部最优回溯和贪心之所以容易混是因为代码结构有点类似。但它们的适用场景完全不同。回溯适合“枚举所有可能性”的问题比如全排列、组合总和、子集。标准模板就三步选择、递归、撤销。下图是我自己的速记方式def backtrack(path, options): if 满足结束条件: 记录结果 return for 每个选择 in options: 做选择 backtrack(path, 新的options) 撤销选择撤销这一步少了会导致状态残留。我写全排列的时候第一次跑出重复结果就是因为撤销写错了位置。而贪心只考虑当前最优不需要回溯关键是要能证明局部最优能推出全局最优。比如“跳跃游戏”只要每一步都维护一个最远可达位置并且判断当前位置是否可达就能在线性时间内得出答案。区分办法很粗暴如果题目要你枚举方案优先回溯如果只问最大、最小、能不能试试贪心或DP。4. 110天刷题计划是怎么执行的4.1 三段式节奏设计阶段时间跨度重点任务第一阶段数据结构基础第1~30天数组、链表、栈、队列、哈希表专项刷题第二阶段算法专题第31~80天双指针、滑动窗口、二分、DP、回溯、贪心专项攻坚第三阶段混合复刷第81~110天随机抽题、模拟面试、错题集中复盘这个节奏设计有几个考虑。第一阶段用相对简单的数据结构题建立手感因为前期最重要的是“写出来”自信心很关键。第二阶段开始上算法思维难度增大每天题目数可以适当减少但每道题要挖得更深。第三阶段最容易被忽略却最实用很多人刷题到最后形成“看一眼就知道是哪个专题”的惯性一旦题目不分类混在一起反而不会写了。混合复刷就是专门打破这种惯性。4.2 一天刷多少题怎么分配我的执行节奏是工作日1到2道新题周末3到4道。但有一个原则从第30天开始一直没变过每完成一道新题必做一道之前错过的旧题。这个“新旧搭配”的操作看起来慢实际效率极高。因为记忆很容易随时间衰减当天听懂、隔一周全忘是常有的事。定时回看你曾经卡住的题才是真正把题目消化掉的时刻。如果哪天状态特别差一道题卡了一小时还是没思路我的建议是直接看题解但看完必须做两件事一是把题解的思路用自己的话写一遍二是隔两天完全独立重做一遍。看题解不可怕看完什么都不做才可怕。4.3 错题本怎么记才有效错题本不是把代码复制一遍就算完。我的做法是把错因分类分三类思路型错误、边界型错误、实现型错误。思路型错误是最值得记录的它代表你真的没想通某个角度边界型错误是粗心靠检查清单来治实现型错误多是细节记录下来防止再犯。我自己用的记录模板日期题目错误类型卡点分析下次复习日期3.9接雨水思路型没想出单调栈维护左边界3.153.10搜索旋转排序数组边界型leftmid导致死循环3.16不要小看这张表。它最大的价值在于“下次复习日期”这一栏会逼着你回到痛苦记忆里而这恰恰是深度学习发生的地方。4.4 面试视角下的“讲题四步”刷题的最终目的不只是AC面试时要能在白板上讲清楚。我后来刻意练习了一个讲题框架一句话概括思路举一个小例子推演过程说复杂度提边界条件。这四步走完面试官对你的评价通常不会太差。练习方式很朴素做完题后打开手机录音限制一分钟讲完这道题然后听回放。你会发现很多“以为自己懂了”的题目在录音卡壳的那一刻就暴露了。这个练习做几次之后代码的书写自信会有肉眼可见的提升。5. 刷题中最容易踩的坑与排查实录5.1 超时不是靠“优化循环”解决的很多人一看到超时第一反应是把循环里的条件写复杂一点或者用一些语法技巧。实际上超时大概率是复杂度问题不是常数优化问题。排查顺序应该像漏斗先看算法复杂度是不是可以接受的再看代码里有没有重复计算最后才考虑用缓存记忆化。举个例子斐波那契数列用普通递归n50以上基本就跑不动了原因是指数级的重复计算。改成记忆化递归或者DP之后瞬间返回。这不叫优化而是换了一个正确的算法思路。所以调试超时第一步永远是回头分析复杂度。5.2 边界条件漏判的典型场景常见边界典型错误检查方式空数组 / 空链表直接访问头节点函数开头判空单元素输入循环条件写错导致进不去手动跑一次size1全是相同元素双指针更新条件漏掉相等情况测试重复值负数混合与0比较时方向判断错单步打印变量二分死循环mid (leftright)/2 时left不前进用左闭右开再看一遍每次提交前花三十秒把这些边界在脑子里过一遍AC率能提升一个档次。这是我踩了不少次提交失败之后总结出的习惯。5.3 面试现场写代码的姿势面试时写代码和平时刷题完全不一样平时可以安静思考环境一变就紧张。我在模拟面试里发现一个规律面试官更看重思路的表达过程而不是最终代码是不是一次通过。如果拿到题没思路先说一个暴力解法再和对方讨论优化方向这远比沉默十分钟好得多。动手写代码之后尽量保持口头解说让面试官知道你在想什么。变量命名也尽量语义化不要写a、b、c这种名字。这些看起来是软技能但实际面试里它们和算法能力同样重要。这110天刷下来的最大心得是我终于把“刷题”从一种焦虑行为变成了一个稳定流程。现在拿到任何一道新题我会下意识先看数据规模估算复杂度上限再想需要什么数据结构最后才动笔。过去那种“上来就写超时再乱改”的坏习惯基本改掉了。如果你也正在刷这套题单我的建议很简单别贪量按专题推进做错题整理定期回到旧题里看看自己是不是真的会了。这样可能前期感觉慢但到第50天以后你会明显感觉到质变。
延伸阅读

更多相关文章

2026/10/20 16:50:43

AI时代如何真正学习:从把AI当答案生成器到当思维陪练

说实话,我和大多数人一样,最开始拿到AI工具的时候是极其兴奋的。这玩意太强了,装个客户端、开个网页,然后把我看不懂的题目、读不进去的长文、懒得总结的PDF一股脑丢进去,几秒钟就给我产出了一篇结构工整、逻辑清晰的回…

2026/10/20 16:50:43

Agent长任务不崩的秘诀:上下文压缩与Checkpoint持久化

Agent 跑到一半,上下文先爆了,这是所有搞过 LLM Agent 的人都会撞上的墙。这个系列写到这里已经是第十六篇,前面一直在拆 DeepSeek-Harness 这个框架怎么把 Agent 的调度、工具调用、多轮推理组织起来,但这几期内容做完之后你会发…

2026/10/20 16:50:43

个人技能管理体系:从搭建技能树到能力资产化

这些年我带过不少人,也时常被人问到同一个问题:你觉得自己最擅长什么?大部分人低头想半天,说出来的还是岗位名称,而不是具体的skill。真正让我开始认真对待skills这件事,是因为我发现自己也掉进过类似的坑&…

2026/10/20 17:46:14

Halcon常用算子详解:从阈值分割到模板匹配的机器视觉实战

做机器视觉的人,不管你是搞检测、定位还是测量,日常工作里打交道最多的就是Halcon那几百个算子。很多新人第一次打开算子列表,满屏英文名,什么threshold、connection、select_shape,翻译软件翻一遍也还是似懂非懂&…

2026/10/20 17:46:14

吃透UIAutomation:从控件树到稳定脚本的Windows界面自动化实践

Windows 界面自动化这条技术路线,但凡碰过的人都知道一个普遍规律:工具一抓一大把,教程满屏都是,可真到了自己要做一个能稳定跑回归的自动化脚本时,问题全冒出来了。定位不到元素、脚本偶尔乱点、换台机器就废……十有…

2026/10/20 17:46:14

用Java判断字符串是否为时间格式:核心工具类详解

做数据清洗和接口对接的时间长了,你会发现一个特别基础但又绕不开的需求:怎么判断一个字符串到底是不是时间格式。用户提交的表单里、合作方导出的文件里、爬虫抓下来的字段里,总有人把“2024-01-15”写成“2024/1/15”,把“15:30…

2026/10/20 17:46:14

鸿蒙 KMP 跨平台实战:Bilibili 应用数据层复用与 NAPI 桥接

简介:这份PDF资料面向已熟悉Kotlin、具备一定鸿蒙开发经验的研发人员,聚焦Kotlin Multiplatform在HarmonyOS上的跨平台落地难题,以鸿蒙版Bilibili开发实践为主线,讲解如何让业务逻辑在鸿蒙、Android与iOS之间复用,从而…

2026/10/20 17:46:14

安全专用大模型SecGPT vs 通用模型Qwen2.5:网络安全分析实战对比

我最初接触这个选题,是因为帮某团队做安全告警降噪时,发现他们已经在用通用大模型分析日志,效果却一言难尽——模型很能聊,但聊出来的结论经常把安全工程师带沟里。后来我把 SecGPT 这类安全专用大模型和通用模型放到同一批真实任…

2026/10/20 17:41:13

物理规律导向视频模型:技术路线、实操要点与常见问题排查

1. 物理规律导向视频模型到底在解决什么问题 视频生成模型这两年迭代速度极快,从最早的几秒模糊片段,到现在能出十几秒甚至更长的连贯画面,进步肉眼可见。但如果你真正拿这些模型做过内容生产,就会发现一个特别尴尬的现象&#xf…

2026/10/19 18:06:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/20 1:05:37

单片机C运行时从启动到多任务:中断安全与共享资源冲突

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

GCC编译四步详解:预处理、编译、汇编、链接实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

FIW线是什么?FEP注塑线与普通氟塑料线的区别及应用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑