当前位置: 首页 > news >正文

【Java实习面试算法冲刺】链表

第4类题型:链表

为什么链表题你感觉思路不难,一写代码却总把链断掉

很多同学刷链表题时,第一反应都是“这题思想不难,就是操作麻烦”。这句话只说对了一半。链表题真正拉开差距的地方,不是你知不知道反转、删除、判环这些套路,而是你能不能在每一步指针修改时都保持清醒。

这类题最容易暴露出几种典型问题:

  • 你知道要改next,但一改就把后续节点丢了。
  • 你会写删除节点,却没提前想到头结点可能变化。
  • 你记住了快慢指针模板,但说不清为什么这样走一定能找到答案。

1. 核心知识点

链表题的难点通常不是算法思想多复杂,而是指针操作顺序很容易错。你必须先养成两个习惯:

  • 改指针之前先保存next
  • 遇到头结点可能变化的问题,优先考虑虚拟头结点dummy

链表高频模型主要有:

  • 反转链表。
  • 合并链表。
  • 快慢指针。
  • 删除节点。
  • 判环。

其中最核心的 3 个模板是:

反转链表

ListNodeprev=null;ListNodecurr=head;while(curr!=null){ListNodenext=curr.next;curr.next=prev;prev=curr;curr=next;}returnprev;

虚拟头结点

ListNodedummy=newListNode(0,head);

快慢指针

ListNodeslow=head;ListNodefast=head;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}

动画辅助理解:改指针前先保存后继

链表题最适合用206. 反转链表建立第一印象。你可以先打开本地动画页:

链表:反转链表分步动画

这个动画最值得盯住的是 4 步:

  • 先明确当前要处理的节点是cur,已经反转好的部分头结点是prev
  • cur.next之前,必须先把原来的后继保存到next
  • 再执行cur.next = prev,完成一个节点的局部反转。
  • 最后整体推进prev = curcur = next,继续处理下一段链。

1 -> 2 -> 3 -> null举例,状态变化可以这样记:

步骤当前状态关键操作为什么这样做
初始prev = null, cur = 1还没改链先明确谁是已反转部分,谁是待处理节点
保存后继next = 2ListNode next = cur.next;不先保存,后面一改cur.next就找不到2
局部反转1 -> nullcur.next = prev;把当前节点指回前驱,完成一小段反转
整体推进prev = 1, cur = 2prev = cur; cur = next;让下一轮继续处理原来的后继节点

2. 这类题在面试里考什么

链表题常见,但能非常直接地看出候选人是否稳。

面试官在看:

  • 你是否清楚每个指针当前指向谁。
  • 你会不会因为修改顺序错误而把链断掉。
  • 你是否知道什么时候该加dummy
  • 你是否理解快慢指针的语义,而不只是机械套模板。

很多候选人链表题不是败在思路,而是败在“指针含义没说清、边界没提前想”。所以链表题的区分度,往往就在这些细节上。

3. 高频题清单

题目来源难度高频属性
206. 反转链表LeetCode 热题 100Easy面试高频
21. 合并两个有序链表面试经典 150Easy基础高频
19. 删除链表的倒数第 N 个结点LeetCode 热题 100Medium高频 Medium
141. 环形链表LeetCode 热题 100Easy高频
142. 环形链表 IILeetCode 热题 100Medium真实面经高频

4. 这类题最容易犯的 3 个错误

  1. 指针还没保存next就直接改链,结果后续节点丢了。
  2. 头结点可能变化的题,不加dummy,边界写得很乱。
  3. 快慢指针会背,但说不清为什么快指针先走n步。

5. 代表题精讲 1

题目

206. 反转链表

思路

这题是链表基本功。核心在于把当前节点的next指向前一个节点,所以每次循环都要做 4 件事:

  1. 先保存curr.next
  2. 再改curr.next = prev
  3. prev前进到curr
  4. curr前进到原来的next

Java 代码

classSolution{publicListNodereverseList(ListNodehead){ListNodeprev=null;ListNodecurr=head;while(curr!=null){ListNodenext=curr.next;curr.next=prev;prev=curr;curr=next;}returnprev;}}

复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

边界提醒

这题最容易漏想的边界其实不复杂:空链表和只有一个节点的链表。好消息是这套写法天然就能覆盖,因为curr == null时循环根本不会进入;只有一个节点时,执行一轮之后也会正确返回它自己。

如果这是面试现场,你可以这样说

这题本质上是逐个节点把指针方向反过来。为了不丢链,我会先保存当前节点的下一个节点,再把当前节点的next指向前驱节点。prev表示已经反转好的部分头结点,curr表示当前要处理的节点。整个过程只需要一次遍历。


6. 代表题精讲 2

题目

19. 删除链表的倒数第 N 个结点

思路

这是快慢指针和dummy的组合题。

为什么要加dummy:因为被删除的节点可能正好是原头结点。

为什么快指针先走n步:这样当快指针走到链表末尾时,慢指针刚好停在“待删除节点的前一个节点”,方便删除。

做法:

  1. dummy -> head
  2. fast先走n步。
  3. slowdummy出发,与fast一起走,直到fast.next == null
  4. 此时slow.next就是待删除节点,执行删除。

Java 代码

classSolution{publicListNoderemoveNthFromEnd(ListNodehead,intn){ListNodedummy=newListNode(0,head);ListNodefast=dummy;ListNodeslow=dummy;for(inti=0;i<n;i++){fast=fast.next;}while(fast.next!=null){fast=fast.next;slow=slow.next;}slow.next=slow.next.next;returndummy.next;}}

复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

边界提醒

这里最关键的边界不是代码长短,而是“删除的可能就是原头结点”。比如链表是1 -> 2 -> 3n = 3,真正要删的是第一个节点。如果你没有先建dummy,就得单独处理头结点变化;而加了dummy之后,这个边界会自动归入统一流程。

如果这是面试现场,你可以这样说

这题我会用虚拟头结点加快慢指针。先让快指针走n步,这样快慢指针之间就保持了固定距离。之后它们一起走,当快指针到达尾部时,慢指针刚好停在待删除节点的前一个位置。用dummy可以统一处理删除头结点的边界。


7. 其余题模板与关键片段

21. 合并两个有序链表

dummy串起来:

ListNodedummy=newListNode(0);ListNodetail=dummy;while(list1!=null&&list2!=null){if(list1.val<=list2.val){tail.next=list1;list1=list1.next;}else{tail.next=list2;list2=list2.next;}tail=tail.next;}tail.next=(list1!=null)?list1:list2;

这类题的核心不是“会不会连”,而是你能不能保证tail始终指向已经合并好部分的最后一个节点。只要这个语义稳定,代码就不容易乱。

141. 环形链表

Floyd 判环:

while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;if(slow==fast){returntrue;}}returnfalse;

为什么它成立:如果有环,快指针每次比慢指针多走一步,它们进入环之后,距离会不断缩短,最终一定会在环里相遇;如果无环,快指针会先走到null

8. 链表题先判断什么

真正写代码前,你可以先问自己 4 个问题:

  1. 这题会不会改动头结点。
  2. 我现在改next之前,后继节点有没有保存。
  3. 这题更像反转 / 删除 / 合并,还是快慢指针问题。
  4. 我当前每个指针的语义能不能用一句话说清。

这 4 个问题回答清楚,链表题大部分错误都能提前拦下来。

9. 错题本记录方式

链表题建议重点记:

10. 面试前 3 分钟速记

11. 最后总结:链表题的核心不是模板,而是指针语义别乱

如果你只能记住一句话,那就是:链表题真正难的地方不是模板多,而是你必须始终知道“当前这几个指针分别指向谁”。

面试时你可以按这个顺序去讲:

  1. 这题头结点会不会变化,要不要先上dummy
  2. 我当前维护的每个指针分别表示什么。
  3. 我改next之前,是否已经把后继保存好了。
  4. 这题的答案是返回prevdummy.next,还是某个相遇节点。

这样你写出来的链表代码会稳定很多,也更容易把思路讲清楚。


上期速递:【Java实习面试算法冲刺】滑动窗口

下一篇:正在路上……
感谢阅读,记得点赞、关注、收藏,欢迎各位评论区交流!!!

http://www.jsqmd.com/news/1138224/

相关文章:

  • 飞马SLAM100 手持激光雷达:13分钟快速模式点云解算实战(附SLAM-GO-POST 3.0配置)
  • 国产打印机二十年突围:从被专利封堵到全链路自主可控的产业逻辑
  • 构建股票预测系统的完整流程
  • 怎么样在遍历列表时动态判断阈值是否被满足并返回相应文本
  • Java毕设选题推荐:基于 SpringBoot 的月嫂排班护理服务系统的设计与实现 基于前后端分离的母婴月子健康档案管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • STAR RNA-seq比对工具:从零开始掌握转录组数据分析的终极指南
  • 数据库工程:Explain执行计划对比实战指南‌
  • 国内高校毕业生最适用的AI论文软件有哪些?
  • Rive渲染器实战:解决跨平台高性能动画渲染难题
  • SO101复现 更新ing
  • 向 Hermes Agent 提交 Bug 修复:从诊断到 CEO 亲自加固的完整记录
  • Meta开发的AI编程助手,真的懂你吗?
  • SFML跨平台多媒体开发实战:构建高性能应用的架构深度解析
  • 2026 降AIGC网站实测盘点:亲测好用,毕业季生存手册
  • Python 知识1
  • FastDFS V6.16发布:支持单服务器多实例部署,新增监控工具!
  • vba检查SolidWorks工程图是否已插入指定名称的图块的实例
  • 3步掌握专业级AI图像增强:让模糊图片秒变高清
  • 华为海思 2025 秋招技术面复盘:3 轮面试 5 大高频考点与 1 个 CDC 难题解析
  • 缓存命中率99%!深挖Reasonix源码,吃透DeepSeek前缀缓存最佳实践
  • 快速掌握:N_m3u8DL-CLI-SimpleG图形界面视频下载工具完整指南
  • 福州翻译机构 越南语基金翻译分析
  • 【安全与故障排查】02-SSH安全最佳实践:禁密码+密钥+端口+防暴破
  • 如何在5分钟内为OBS Studio添加智能面部追踪功能
  • 企业知识库实战:从 0 到 1 落地全记录
  • 延安本地企业做GEO靠谱本地服务商推荐:延安企业GEO服务商优选指南
  • 当你的浏览器成为资源宝库:3分钟解锁全网视频音频的智能下载新体验
  • 毕业季论文必备!好用的AI论文工具,成稿速度破纪录
  • 如何评价腾讯7 月 6 日发布的混元 Hy3 ?
  • 线控转向 vs 传统舵机:智能车方向执行机构 2 方案对比与选型指南