尧图精选

Java程序员刷LeetCode实战指南:分类刷题与面试提效方法论

🕒 发布时间:2026/11/5 7:56:34 📁 来源:尧图网络
Java 程序员刷 LeetCode这个话题几乎所有准备跳槽或者参加校招的人都会撞上。我看过太多人买了会员、下载了题解包、立下“狂刷 500 题”的 flag结果刷了两个月还停留在两数之和。不是因为刷题没用而是打开方式不对。LeetCode 不是刷题 App是一套可以反复研磨的思维训练场Java 也不是你的障碍用对了反而是优势。这篇内容不是教你怎么背题而是分享一套我亲测有效的方法论从怎么选题、怎么分类、怎么看题解到 Java 写算法的细节、面试现场的应对以及刷题过程中一定会踩的坑。这些都是我在实际刷题和面别人的过程中沉淀下来的东西希望对同样在 Java 这条路上往前走的人有点帮助。1. 先把方向搞清楚刷题到底在刷什么1.1 别把 LeetCode 当成刷题机器很多人把 LeetCode 当成一个“题库”刷题过程就是“打开题目 - 憋一会儿 - 看题解 - 背下来 - 下一道”。这样刷一个月AC 数量涨得飞快但遇到新题还是没思路面试官换个问法就卡住。问题的根源在于你只刷了“答案”没练“能力”。算法题本质上在训练五件事问题建模、数据结构选型、边界条件感知、复杂度分析、代码实现与调试。拿“两数之和”举例普通人想的是一次循环用哈希表存值但如果你认真复盘会发现这道题背后还牵出了 HashMap 的查找原理、数组和 Map 的取舍、空间换时间的思想甚至还能延伸到 Java 里 HashMap 的扩容和哈希冲突。同样一道题有人刷一遍只是一道题有人刷一遍能串起一整个知识体系。所以我一直跟组里的新人说LeetCode 刷题的核心不是“AC 数量”而是你每做一道题有没有把“为什么这样做”想明白。简单题练的是基本功中等题练的是思维框架困难题练的是耐心和边界处理能力。如果你每天都只挑简单的刷那和刷抖音没区别。1.2 结合 Java 特性和面试需求制定策略Java 程序员刷题要有一个额外的视角算法题和 Java 基础从来不是割裂的。面试官出了一道算法题往往会在你写完代码后顺势追问底层实现。比如你写了两数之和他用 HashMap 存储面试官就会问 HashMap 什么时候扩容、什么时候变红黑树你写了 LRU面试官会问 LinkedHashMap 为什么能维持插入顺序你写了并发相关的题目面试官就会往 AQS、synchronized、线程池方向引。正确的做法是提前建立一张“算法题 - Java 知识点”映射表。刷题的时候多做一步这道题的解法用到了哪个 Java 类它的底层是怎么实现的。下面这张表我在面试前反复翻了很多遍非常管用算法题型对应 Java 知识点HashMap 计数 / 去重HashMap 底层结构、哈希冲突、扩容、红黑树链表反转 / 环检测对象引用传递、不可变对象、哨兵节点设计LRU 缓存LinkedHashMap、双向链表、并发安全生产者消费者模型wait/notify、ReentrantLock、Condition、阻塞队列栈 / 表达式求值Deque、栈帧概念、运算符优先级树相关递归与迭代、TreeMap / TreeSet 红黑树实现排序 / TopKComparable、Comparator、PriorityQueue 堆结构这个思路最大的好处是节省时间。人家刷题是单线程你是双线并行一道题同时复习算法和 Java 基础。到了面试阶段你会发现那些看起来很难应付的连环追问其实早就在刷题的时候埋好了伏笔。2. 建立正确的刷题节奏与方法2.1 按专题分类刷而不是按题号刷很多新手最容易犯的错就是老老实实从 1 题刷到 100 题。这种按题号刷的方式效率极低因为题目难度忽高忽低知识点也完全打散你今天刷一道链表明天刷一道动态规划大脑根本来不及形成归纳遇到新题依然没抓手。正确做法是按专题分类刷每个专题集中火力一次把一类题吃透。比如花一周只刷链表题反转链表、环形链表、合并两个有序链表、K 个一组翻转链表全部过一遍。这个阶段你可能看到任何链表题都有肌肉记忆知道先考虑哨兵节点再考虑双指针最后考虑递归或者迭代。这就是“题感”的来源不是背题是脑子里建立了这一类题的解法模板。我建议的专题顺序是这样的专题建议题量代表题数组与双指针10-15 题三数之和、盛最多水的容器、接雨水哈希表与字符串8-10 题两数之和、无重复字符的最长字串链表10-12 题反转链表、环形链表、合并 K 个升序链表栈与队列8-10 题有效的括号、最小栈、基本计算器二叉树15-20 题二叉树的中序遍历、最近公共祖先、路径总和回溯10-15 题全排列、组合总和、N 皇后二分查找8-10 题搜索旋转排序数组、爱吃香蕉的狒狒动态规划20-25 题爬楼梯、最长递增子序列、编辑距离排序与堆8-10 题数组中的第 K 个最大元素、前 K 个高频元素贪心6-8 题跳跃游戏、买卖股票的最佳时机图论与并查集6-10 题岛屿数量、课程表位运算5-8 题只出现一次的数字、比特位计数这个表不是说必须严格按它来而是提醒你要“成体系”地刷。专题刷的另一个隐藏好处是方便复盘。同一专题刷完你回头扫一眼错题很容易总结出规律链表题喜欢考快慢指针区间问题要么排序要么差分括号问题首选栈。2.2 从热门 100 题入手把握核心题型如果时间紧张没空像上面那样系统分类那就从 LeetCode 热门 100 题开始。这 100 题是全世界面试频率最高、覆盖题型最全的一批题目。刷过的人都知道很多大厂的笔试题要么直接是原题要么是把原题改个壳。把这 100 题吃透投递大厂时的算法底子基本就有了。但热门 100 题不是让你从头到尾顺一遍了事而是要用“分类法”去刷。拿到这 100 题后先按算法标签分堆Tree、DP、Two Pointers、Backtracking 各有多少题然后每天挑选同一标签下的三五道题集中做。这样既不脱离高频范围又保留了专题刷的效率。另一个要点是热门题并不都是简单题里面藏着不少困难题。比如“接雨水”“编辑距离”“正则表达式匹配”。遇到这种题不要死磕30 分钟没有思路就暂时看题解但看题解不是目的目的是把解法思路整理成自己的话讲一遍。你要能做到合上题解第二天把这道题的四个核心步骤写出来那这道题才算真正 pass。顺便说一句LeetCode 热门题也是解读 Java 八股文的绝佳素材。比如热门题里的“基本计算器 I/II”既考栈的使用又考运算符优先级做完之后你其实可以顺手去复盘 Java 表达式求值、逆波兰式转换这些知识点。一道算法题提供的养分往往比一次背八股文还多。2.3 题解怎么看“三遍刷法”是关键我曾经带过一个小徒弟刷题非常猛三个月干了 300 多道结果模拟面试的时候连一道中等难度的“二叉树层序遍历”都讲不清楚。他的日常就是遇到不会的题看题解复制粘贴AC 后高高兴兴标记完成。这种方式刷得再多也只是感动自己。我现在跟所有新人推荐的是三遍刷法也可以叫“三刷策略”第一遍独立求解 30 到 40 分钟。不要求一定 AC但你必须真的动手画图、推演、写伪代码。哪怕最后一行都写不出来你也已经知道自己卡在哪这一步的“卡点”就是后续学习的重点。第二遍参考题解后合上题解重新写。这一步的关键是不要照抄代码。理解了解题思路后用自己的话、自己的变量命名、自己的代码风格再写一遍。写到一半忘了不要紧重新看题解再理解再合上再写直到能独立 AC。第三遍隔天或一周后重做。这一步是检验你真正掌握没有。能顺利做出来说明这道题的解法已经进入你的长期记忆做不出来说明上次只是短期记忆需要重新回去看题解。三遍刷法看起来费时间但实际上每一遍的收获都比闷头刷新题大得多。刷 10 道题每道三遍效果远超刷 30 道题每道一遍。这里还建议准备一个模板库把常考算法的固定写法放进去比如二分查找的几种模板、快排、并查集、树的遍历框架。每次刷题前看一眼相当于赛车手赛前熟悉赛道。3. 用 Java 刷题的关键技巧与代码习惯3.1 数据结构选型Java 集合的正确打开方式Java 在 LeetCode 上最大的优势是标准库丰富集合框架用好了能让代码又短又不容易出 bug。但用不对的话也会掉进各种细节坑。先说 HashMap。刷题时最常用的就是getOrDefault、merge、computeIfAbsent这几个方法。统计字符频率时map.put(c, map.getOrDefault(c, 0) 1)比“先 containKey 判断再 put”简洁得多。merge更推荐可以配合 Lambda 实现逻辑map.merge(c, 1, Integer::sum)。这种写法在函数式风格上很干净但要注意代码可读性面试时要能解释清楚每个参数的含义。再比如 PriorityQueue。Java 默认是小根堆但很多 TopK 问题需要大根堆或自定义排序。一个容易踩的坑是 Lambda 比较器直接写(a, b) - b - a在极端情况下会溢出。比如两个 Integer 的差超过 int 范围结果就会出错。虽然 LeetCode 测试用例一般不会卡这个点但良好习惯是用Integer.compare(b, a)或者(b, a) - b.compareTo(a)。面试时你要是能主动说出这个坑反而是加分项。然后是 ArrayDeque 和 LinkedList 的选择。很多人在需要栈或者队列操作时随手选 LinkedList其实刷题场景下 ArrayDeque 大部分时候是更好的选择。它的连续内存访问更高效也避免了链表节点对象带来的额外内存开销。需要访问头尾元素时ArrayDeque 的pollFirst、pollLast、offerFirst、offerLast非常顺手。但要特别注意一点ArrayDeque 不允许存放 null 元素如果你需要判断“是否为空”并允许 null 占位那就用 LinkedList 或单独搞一个状态变量。Arrays.asList和Collection互转也是高频操作。数组转 List 再转回数组经常有人写出list.toArray(new Integer[0])然后才发现拿到了Integer[]而不是int[]。Java 8 之后流处理能解决大部分问题但 LeetCode 的简单题里老老实实用循环比用 stream 更直观。我还见过有人在循环里用String 拼接字符串几千次循环问题不大但到了字符串拼接超过几万次时性能会明显劣化说好的不要刷出来的代码还没跑就超时了。建议到哪都老老实实用 StringBuilder。3.2 注意 Java 的边界与性能陷阱Java 刷题有一个很烦人的特点一些平时开发中很少遇到的边界问题LeetCode 会精确地逼你踩一遍。最经典的当然是 int 溢出。典型例子是二分查找的mid (left right) / 2。看起来人畜无害但如果 left 和 right 都很大两者之和直接越了 int 上限变成负数。正确写法是mid left (right - left) / 2或者用无符号右移mid (left right) 1。面试时能说出用来避免溢出的细节说明你对 Java 整型运算吃得很透这个印象分会很扎实。再说一个坑Integer 缓存。Java 中对 -128 到 127 之间的 Integer 会缓存对象直接用比较两个值为 100 的 Integer 对象可能返回 true但换成 1000 就返回 false。刷题时我用过几次对象比较调了半个小时才发现是这里的问题。所以算法题里凡是比较数值统一用equals方法或者开局就拆成基本类型 int 来做事。递归深度也是一个需要注意的点。Java 的 JVM 栈深度默认并不大递归过深很容易抛出 StackOverflowError。LeetCode 上一些树形结构的题测试数据不小心就会让你递归一万层。遇到这类情况要么换成迭代 显式栈要么看看能不能尾递归优化不过 Java 对尾递归的支持并不好更靠谱的办法是写成循环。还有位运算符的优先级问题。很多 Java 程序员写if (flag 1 0)是会直接编译报错的因为的优先级高于。正确写法是if ((flag 1) 0)。这类细节虽然和算法本身无关但代码写得不对就别谈 AC 了。刷题时保持对字节码层面行为的敏感不仅能减少低级错误也能在面试的代码 review 环节更从容。3.3 代码组织与可读性写给面试官看的算法代码LeetCode 上写代码和平时在公司写业务代码是不同的但也有相同点都要让别人能看懂。面试时你写的算法代码是讲给面试官听的不是丢在题解区自娱自乐。有一个原则我一直强调变量名要能表达业务含义而不是a、b、tmp满天飞。比如快慢指针题里slow和fast就比i和j好得多二分查找里left、right、mid永远比l、r、m更具可读性。另一个建议是在动手写代码前先用一到两行注释写出核心思路。比如// 双指针一个指向遍历位置一个指向待交换位置这个习惯有两个好处一是你在面试时边写边解释注释就是讲稿二是万一代码写到一半卡住回头看看注释能帮你快速找回思路。还要养成先处理边界条件的好习惯。空数组、只有一个元素、全是重复元素、目标不存在这些情况在 LeetCode 的测试用例里几乎必然出现。我自己的习惯是写完主逻辑后立刻检查函数入口处是否覆盖了空值判断if (nums null || nums.length 0) { return 0; }这行代码看起来简单却是很多人 AC 路上最大的绊脚石。本地调试技巧方面我强烈建议在 IDE 里建立一个小的测试框架。LeetCode 的在线编辑环境足够练习但遇到难题还是需要本地打断点。我会把题目输入写成字符串解析成数组后走一遍算法再用System.out.println打印关键中间值。调试完成后记得把输出语句删掉不然面试时要展示代码时会显得很业余。4. 面试场景下的 LeetCode 实战4.1 手写算法与八股文的关系很多 Java 候选人有个误区算法题是算法题八股文是八股文两座山分别爬。实际上面试官看得很清楚这两者是同一棵树的枝条。算法题考查的是你的逻辑能力八股文考查的是你的语言功底和对底层原理的理解。但面试现场这两部分经常是连着的。最典型的情况就是面的 Java 岗位面试官让你手写一个“线程安全的 LRU 缓存”你写完 LinkedHashMap 的代码他随口就问“LinkedHashMap 为什么能维持访问顺序accessOrder 是怎么工作的”如果你只刷题不思考这一段就哑火了。反过来如果你刷题时就想到了升级访问顺序、重写 removeEldestEntry 这些点那么你不仅能应对追问还能主动把话题引到你熟悉的领域。我建议按下面这个思路过题每刷完一道题花 5 分钟想想“这道题和 Java 的哪个类有关系”。如果是二叉搜索树相关题目就去复习一下 TreeMap 的源码如果是堆排序就去复习 PriorityQueue 的 siftDown 和 siftUp如果是并发相关的题目就去理解 synchronized 和 ReentrantLock 的区别以及 AQS 的 CLH 队列大致是怎么工作的。这样刷题从四小时中抽出二十分钟查 Java 源码比单独背八股文印象深得多。4.2 面试中如何讲清楚一道算法题面试算法题不是要求你闷头写对就完事而是要在交流中让面试官了解你的思维过程。我模拟面试过很多人发现一个普遍问题候选人题目还没看完就开始写代码也不问输入输出的边界。这在面试里其实是很减分的因为面试官会觉得你缺少需求分析和沟通意识。我推荐的表达框架是“I-S-O-C”IIdentify先明确问题。确认输入是什么输出是什么是否允许有空值数字范围多大。比如“输入数组会不会为空如果为空我直接返回 0 行不行”SSolution再讲思路。先给一个最直观的暴力解然后分析复杂度再说如何优化。这样能让面试官看到你有“从坏到好”的优化意识这是真实工作中非常重要的能力。OObtain验证复杂度。把时间和空间复杂度讲清楚最好能说明你为什么选择了这种数据结构它的均摊复杂度是多少。CCode最后再写代码。写的过程中每写几行就简单说一句在干什么写完之后跑一个小例子手动验证。这套框架尤其对社招候选人重要因为社招面试官看重的就是沟通协作和系统化思考能力。代码写得快不是核心诉求把思路完整表达出来才是。4.3 高频考点速查与周赛训练面试算法考来考去离不开几类题型。我做了一个高频考点速查表也是专门给准备面试的同学整理的很快就到面试阶段的时候直接照着复习考点典型题核心思路数组双指针三数之和、接雨水排序 左右指针或预处理最高值字符串最长回文子串中心扩展 / 动态规划链表反转链表、环形链表迭代指针 / 快慢指针二叉树层序遍历、最近公共祖先BFS 队列 / 递归分解动态规划打家劫舍、编辑距离状态定义 转移方程回溯算法全排列、组合总和递归 剪枝二分查找爱吃香蕉的狒狒对答案进行二分栈与表达式基本计算器双栈 / 单栈 sign 标记这里尤其要说说二分查找里的经典题爱吃香蕉的狒狒。这个题表面上是在求“速度”实际上就是一个对结果值域做二分的模板题。先找到最小速度 1 和最大速度 max(piles)然后判断每个速度是否能在 h 小时内吃完二分逼近最优解。这类“把答案当成搜索空间”的思路在算法题里出现频率极高练熟一题能带动一片。除了常规刷题我建议大家定期参加一下 LeetCode 周赛比如最近比较典型的周赛 430 这样的场次。周赛有三个好处限时模拟面试、题量大能高强度训练、通过看排行榜了解大众解法思路。第一次参加可能只能做出两道题坚持参加几场后你的思路速度和抗压能力都会显著提升。用周赛来检验自己比反复刷旧题更能暴露真实水平。5. 常见问题与避坑经验实录5.1 刷了 100 题还是没感觉问题到底出在哪我遇到过很多读者跟我抱怨“学长我已经刷了一百多题了但面试的时候看到新题还是脑子里一片空白。”仔细一问发现普遍存在这么几个问题。一是独立思考的时间太少。他们的日常是看五分钟没思路就直接翻题解看完觉得自己懂了实际上从来没过“卡住”的阶段。但你只有真的卡住大脑才会把这道题的解法路径和各条弯路一起记录下来。不卡住的学习本质上是无效学习。解决方法是强制自己最少想 30 分钟哪怕想不到最优解也要把自己想到的暴力解法写出来。二是复盘不够。刷完一道题就急着刷下一道导致前面做的题全忘了。算法题的相似度其实很高如果你每道题都单独记忆记忆量太大根本不可能记住。正确做法是每刷完一个专题回到专题入口把这一类题目扫一遍总结共性解法。比如动态规划的题做多了你会发现大多数情况都在“定义 dp 数组 - 写转移方程 - 初始化 - 确定遍历顺序”这个框架里。三是简单题刷太多。简单题练手没问题但如果你天天沉浸在简单题里永远不会遇到需要你设计复杂算法的场景。建议每周至少做两道中等难度和一道困难难度难度上去了回头做简单题就是降维打击。5.2 时间不够用不同时间预算下的刷题策略不是每个人都有半年时间从容刷题。很多人是在准备跳槽的间隙里挤时间所以不同时间预算应该匹配不同策略。两周冲刺版如果你的面试在两周后就别搞什么长期计划了。直接集中在热门 100 题的高频前 50 题外加目标公司的面经题。每天做 5 到 8 道上午做新题下午复盘旧的晚上背诵高频模板。这个阶段不求所有题都能独立 AC但每道题的解法都要能用自己的话讲出来。一个月巩固版可以用第一周完成“数组、哈希表、链表、栈”四个基础专题第二周完成“二叉树、回溯、二分”第三周专注“动态规划”和“贪心”第四周用热门题、模拟面试和周赛做实战检验。每天保证两小时周末可以加量。三个月长线版这属于系统性提升。按我前面的专题分类表逐个专题刷每个专题留出 5 天的消化时间。前两个月稳步推进第三个月开始做高频题和综合模拟。长线的关键是不能前两周发力过猛导致后面摆烂保持每天一小时以上的稳定输入比周末突击五小时更有效。5.3 从笔试到面试的最后一公里很多人以为笔试过了就万事大吉实际上现在很多大厂的面试环节技术面会持续到最后一轮每一轮都有手撕代码。笔试和面试里的算法题考察点其实不太一样。笔试看的是 AC 率也就是你能不能把所有测试用例都跑通所以笔试阶段能暴力就暴力能多写一个剪枝就多写一个最后再考虑优化。但面试看的是思维过程和代码可读性你上来直接写最优解当然好但你如果讲的清楚“我是怎么从暴力想到优化的”其实比直接甩最优解更受欢迎。另一个区别是时间压力。笔试的时间相对宽裕你可以反复调试提交错几次也没关系。面试时你就没有太多试错机会尤其是白板写代码写错了划掉重写的成本很高。这个能力没法临时抱佛脚只能靠平时刷题时有意识地训练“一遍过”的能力。我的习惯是把每道题都当成面试题来做先讲思路再动手写写完自己用测试用例验证一遍不依赖在线判题系统。这个习惯坚持下来面试手撕代码的时候会非常稳。最后再分享一个小技巧一定要建立自己的错题本但不要只记题目和解法还要记下“我当时卡在了哪里”。过了两周回头看你会发现很多坑都是重复出现的比如没考虑数组为空、二分边界写错、递归返回值忘记处理。把这些高频错误固化成检查清单每次写完代码对照检查一遍AC 率会提升一大截。刷题这件事没有捷径但确实有更聪明的路线希望这些经验能帮你少走些弯路。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →