图解题库 / 链表 · 双指针

206. 反转链表

简单 含交互动画

学完这道你应该能: 说清它为什么用「双指针」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

把单链表整个反转:每个节点的指针都指向它原来的前一个

输入 = 1 → 2 → 3 → null
输出 = 3 → 2 → 1 → null

思路解析

可以遍历把值压进数组/栈,再倒着 new 一条新链表——但要 O(n) 额外空间,还白白新建了节点。更优雅的是原地:只改指针指向,O(1) 空间。

prev 跟在后面(初始 null)、cur 是当前节点。每一轮都做四个动作:①用 next 记住下一个(防断链);② 把 cur.next 掉头指向 prev(原来的箭头先断开、再接到 prev);③ prev 前进一步;④ cur 前进一步。cur 走到 null 时,prev 就是新头。下面一帧一个动作慢放。

起点 · prev=null, cur=头:cur 指向头节点 1,prev 此刻是 null(空)。准备把箭头一根根掉头。

① 记住 next = 2:动手前先用 next 抓住 2。一旦把 1 的箭头改了,就再也找不到后面——「先记 next」是不断链的命根子。

② cur.next 掉头 → prev(null):执行 cur.next = prev:1 原来指向 2 的箭头先断开(图上变成 ·),改指向 prev=null。还好 next 仍抓着 2,没丢。

③④ prev、cur 各前进一步:prev 来到刚处理完的 1、cur 来到 2。第一轮四步走完,1 已经「翻好」(它的箭头朝向 null)。

① 记住 next = 3:第二轮,同样先用 next 记住 3。

② cur.next 掉头 → prev(1):cur.next = prev:2 原来指向 3 的箭头断开(右边变 ·),改指向 prev=1——于是 2 → 1(左边箭头变 ←)。next 仍抓着 3。

③④ prev、cur 各前进:prev 前进到 2、cur 前进到 3。第二根也翻好了。

① 记住 next = null:第三轮,记 next = 3 的下一个,发现是 null——说明 3 是原来的最后一个节点,这会是最后一轮。

② cur.next 掉头 → prev(2):cur.next = prev:3 改指向 prev=2,3 → 2(右边箭头变 ←)。三根箭头现在全部掉头完毕。

③④ 完成 · cur=null, prev=新头:prev 前进到 3、cur 前进到 null,循环结束。此刻 prev 停在 3——它就是反转后的新头:3 → 2 → 1 → null。

链表操作的通用心法:改指针前,先用临时变量抓住会丢失的那一端。反转、删除、合并都靠它,绝不能让链断在手里。

参考代码(Python)

Python
1def reverseList(self, head):
2    prev, cur = None, head
3    while cur:
4        nxt = cur.next        # ① 记住下一个
5        cur.next = prev       # ② 箭头掉头
6        prev = cur            # ③ prev 前进
7        cur = nxt             # ④ cur 前进
8    return prev               # prev 是新头

复杂度分析

  • 时间复杂度:O(n) —— 每个节点走一次
  • 空间复杂度:O(1) —— 只用三个指针

套路模板

记住骨架:prev 跟随、先存 nxt、再改 cur.next、最后双双前进。把「改 cur.next」换成不同操作,就能做删除、去重、两两交换。

Python
1# 凡是「一边遍历一边改指针」的链表题都套
2prev, cur = None, head
3while cur:
4    nxt = cur.next        # 先抓住后面,防断链
5    ...                   # 改 cur.next(掉头/跳过/接走)
6    prev, cur = cur, nxt  # 一起前进一步

易错点

  • 先 cur.next=prev 再记 next → ✅ 必须先 nxt=cur.next(顺序反了,改完就找不到后面,链断了)
  • 返回 cur → ✅ 返回 prev(循环结束时 cur 已是 null,prev 才是新头)
  • prev 初始化成 head → ✅ prev 初始为 None(原来的头反转后要指向 null)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →876. 链表的中间结点 ← 返回题库