news 2026/1/10 7:55:20

力扣 Hot 100 之 206. 反转链表:面试官的“开胃菜”

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣 Hot 100 之 206. 反转链表:面试官的“开胃菜”

206. 反转链表这道题在链表界的地位,大约等同于编程语言里的 Hello World。

虽然它是简单题,但据我观察,能一遍 bug free且能清晰讲出递归逻辑的人,其实并没有想象中那么多。很多人脑子会了,手一写,NPE(空指针)了,或者链表断了。

今天咱们就来彻底搞定它,顺便聊聊怎么在面试里把这道题写出“花”来。

题目是个啥?

给你一个单链表的头节点head,请你反转链表,并返回反转后的头节点。

输入:1 -> 2 -> 3 -> 4 -> 5 -> NULL

输出:5 -> 4 -> 3 -> 2 -> 1 -> NULL

看着简单吧?不就是把箭头调个头吗?

嘿,链表这东西最烦人的就是:由于它是单向的,你一旦回头,就找不到前任了;一旦往前走,就找不到后路了。 所以,操作指针的时候得格外小心。


策略一:双指针迭代法

这是最推荐的面试写法。逻辑清晰,空间复杂度 O(1),不容易出错。

核心心法:三人行

虽然叫双指针,但其实我们需要三个变量来玩转这场“移形换影”:

  1. curr(当前节点):我现在在哪。

  2. prev(前驱节点):我要把箭头指给谁(我的新后继)。

  3. next(临时节点):最重要的备胎。在我改变心意指向prev之前,我得先记下来我原本要去哪,不然一断链,后面的节点全丢了。

动图脑补流程

想象一下,你站在curr(比如节点 2) 的位置:

  1. 备份:先把curr.next(节点 3) 存到next变量里。(防丢失)

  2. 掉头:把curr.next指向prev(节点 1)。(关键一步,链子反了)

  3. 挪窝

    • prev往前走一步,变成curr

    • curr往前走一步,变成刚才备份的next

class Solution { public ListNode reverseList(ListNode head) { // prev 初始化为 null,因为反转后,原本的头节点要指向 null ListNode prev = null; ListNode curr = head; while (curr != null) { // 1. 记下原本的下一步去哪(保存现场) ListNode nextTemp = curr.next; // 2. 斩断情丝,回首掏(指针反转) curr.next = prev; // 3. 整体向后移动 prev = curr; curr = nextTemp; } // 循环结束时,curr 是 null,prev 才是新的头节点(原本的尾巴) return prev; } }

防坑指南:

  • 千万别忘了最后返回的是prev,不是curr(循环结束时curr已经是null了)。

  • 别忘了初始化prev = null,否则反转后的尾巴没法结束。


策略二:递归法

如果你想在面试官面前秀一下你的抽象思维能力,或者想让代码看起来短小精悍,可以用递归。

但说实话,这玩意儿非常绕,脑子不好使的时候容易把自己绕进去。

核心心法:甩锅

递归的精髓在于信任。

假设我们有一个函数 reverseList(head),它的作用是把以 head 为头的链表反转,并返回新的头。

面对1 -> 2 -> 3 -> 4 -> 5

  1. 我(节点 1)想反转整个链表。

  2. 我太懒了,我先对 head.next(也就是节点 2)说:“兄弟,你带着后面那帮人先去反转一下。”

    ListNode newHead = reverseList(head.next);

  3. 假设第 2 步成功了,现在的局面是:

    1 -> 2 <- 3 <- 4 <- 5

    注意:此时 1 还连着 2,但 2 已经是后面那串反转后的链表的“尾巴”了。

  4. 关键操作:我要让 2 指回 1。

    head.next.next = head; (翻译:我下家的下家,变成我自己)

  5. 断后路:1 现在是新的尾巴了,必须指向 null,否则就死循环了。

    head.next = null;

class Solution { public ListNode reverseList(ListNode head) { // 递归终止条件:链表为空,或者只有一个节点,那还反转个屁,直接返回 if (head == null || head.next == null) { return head; } // 1. 甩锅:先让后面的节点去反转 // newHead 只是为了最后返回用,中间过程完全不碰它 ListNode newHead = reverseList(head.next); // 2. 关键:把当前节点挂到后面那串链表的尾巴上 // head.next 此时就是后面那串的尾节点 head.next.next = head; // 3. 断开原来的连接,防止环路 head.next = null; return newHead; } }

优缺点分析:

  • :代码行数少,逻辑看起来很高级。

  • :空间复杂度是 O(N),因为要压栈。如果链表非常长,可能会StackOverflow。在工程项目里,还是老老实实写迭代法吧,别搞这些花里胡哨的。


总结

反转链表这道题,属于**“肌肉记忆”**级别的题目。

  • 面试求稳:写迭代法(双指针),解释清楚prev,curr,next的作用。

  • 面试求异:如果面试官问“能不能用递归”,你再反手甩出第二种解法,并顺便聊聊递归栈的深度问题,B 格瞬间拉满。

最后,记住这句话:操作链表前,先把next存起来,不然链表断了,神仙也救不回来。

去刷题吧,祝大家都能把 offer 拿到手软!

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

探索图像滤波去噪:MATLAB GUI的奇妙之旅

图像滤波去噪 MATLAB GUI【带报告】 本链接包含 MATLAB代码&#xff0c;代码&#xff0c;【带word 大报告】。 对图像添加高斯 噪声、椒盐噪声&#xff0c;可进行 均值滤波、中值滤波、同态滤波、小波阈值去噪等多种处理。在图像处理领域&#xff0c;噪声就像是讨人厌的小恶魔&…

作者头像 李华
网站建设 2025/12/14 21:00:58

vue基于Spring Boot的军事论坛军迷交流平台_6c496w86

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring B…

作者头像 李华
网站建设 2026/1/4 21:36:55

vue基于Spring Boot的灌区取用水量调配信息管理系统的应用和研究_2dw80bw4

目录 具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring…

作者头像 李华
网站建设 2026/1/1 11:22:15

vue基于Spring Boot的检察院企业单位会议记录系统的应用和研究_44l22b02

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring B…

作者头像 李华
网站建设 2025/12/14 20:57:41

嵌入式周记1

Duration&#xff1a;12月8日&#xff08;周一&#xff09;----10月14日&#xff08;周日&#xff09; 文章目录Duration&#xff1a;12月8日&#xff08;周一&#xff09;----10月14日&#xff08;周日&#xff09;总结&#xff1a;例程1、timg_32bit_timer_mode_periodic_sle…

作者头像 李华