206. 反转链表(Reverse Linked List)
难度:简单 | 主题:链表、递归
题目
给你单链表的头节点 head,请你反转链表,并返回反转后的链表。
示例
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
思路
先讲个故事:一列火车掉头
一列火车车头朝前挂着 5 节车厢。你想让它变成车尾朝前。怎么办?
方法一:一节一节拆 —— 从车头开始,每节车厢拆下来,一个一个堆到前面去。
方法二:告诉司机”开到终点再回头” —— 递归到最后一节,然后从后往前重新挂。
引导式推导:从迭代到递归
第 1 层:迭代(三指针)
逐个反转 next 指针方向。需要三个指针:prev(前驱)、curr(当前)、nxt(后继)。
初始:prev=None curr=①→②→③→None
第1步:①→None, prev=①, curr=②
第2步:②→①, prev=②, curr=③
第3步:③→②, prev=③, curr=None → 返回 prev
第 2 层:递归(从后往前)
递归到尾节点,回溯时反转箭头。关键操作:head.next.next = head。
递归到 ⑤,返回 ⑤
回溯到 ④:⑤→④
回溯到 ③:④→③
...
graph LR subgraph 迭代反转 A["prev=None<br/>curr=①→②→③→④"] --> B["nxt=②<br/>①→None"] B --> C["prev=①<br/>curr=②→③→④"] C --> D["nxt=③<br/>②→①<br/>prev=②<br/>curr=③→④"] D --> E["...直到 curr=None"] E --> F["返回 prev=④"] end style F fill:#ffd700
| 解法 | 时间 | 空间 |
|---|---|---|
| 迭代 | O(n) | O(1) |
| 递归 | O(n) | O(n) |
代码
# 迭代(推荐)
def reverseList(self, head):
prev, curr = None, head
while curr:
nxt = curr.next
curr.next = prev
prev, curr = curr, nxt
return prev
# 递归
def reverseList(self, head):
if not head or not head.next:
return head
new_head = self.reverseList(head.next)
head.next.next = head
head.next = None
return new_head
复杂度
| 解法 | 时间 | 空间 |
|---|---|---|
| 迭代 | O(n) | O(1) |
| 递归 | O(n) | O(n) |
实战考量
频率分析
出现在:链表”必会基本功”,约 60% 的 AI Agent 常会考到,要求闭眼写出迭代版。不可能不会——不会这题链表部分直接凉。
延伸思考
Q:递归版的时间和空间复杂度?
A:时间 O(n),空间 O(n)——递归栈深度等于链表长度。
Q:反转前 n 个节点怎么做?
A:记录第 n+1 个节点作为后继,反转前 n 个后接上。需要额外参数 tracking。
Q:反转链表和两两交换有什么区别?
A:反转是全部逆序;两两交换是相邻两节点为一组交换位置。后者指针操作更复杂。
易错点
-
nxt要在修改curr.next之前保存 -
最后返回
prev不是curr(curr 是 None) -
递归必须
head.next = None,否则头尾互指成环
生活类比
反转链表 → 一列火车掉头
迭代法:从车头开始,一节节拆下来重新挂——新挂的永远是新头。递归法:开车到最后一节,然后从后往前重新编组——最后一节变成车头。
相关题目
| 题目 | 关系 |
|---|---|
| 24两两交换链表中的节点 | 指针操作同族 |
| 92反转链表II | 局部反转 |
| 25K个一组翻转链表 | 分段反转 |
→ 返回题单:LeetCode学习路线图 > 四、链表
速记卡(面试闪卡)
Q1:一句话讲清「206. 反转链表(Reverse Linked List)」到底是什么?
A:反转单链表,让头变尾、指针全部反向。
Q2:思路 —— 怎么理解?
A:像一列火车掉头:迭代法一节节拆下重挂,递归法开到车尾再倒着编组。核心是 Three Pointers(三指针)prev/curr/nxt 逐个反指。
Q3:代码 —— 怎么理解?
A:迭代三指针:nxt 先存 curr.next,再把 curr.next 指向 prev,prev、curr 后移;返回 prev 不是 curr。递归靠 head.next.next = head 回溯反指。
Q4:复杂度 —— 怎么理解?
A:迭代时间 O(n)、空间 O(1);递归时间 O(n)、空间 O(n)(递归栈等于链长)。闭眼写出迭代版是基本功。
Q5:实战考量 —— 怎么理解?
A:链表”必会基本功”,约 60% 考到,要求闭眼写迭代版。易错:nxt 要在改 curr.next 前存、返回 prev、递归要 head.next=None 防成环。
Q6:核心速记主线有哪些?
-
迭代三指针:nxt 先存,再反指 prev,prev/curr 后移
-
递归:到尾节点回溯,head.next.next = head 反指
-
迭代 O(n)/O(1),递归 O(n)/O(n)
-
易错:先存 nxt、返回 prev、递归置空防环
口诀
A:火车掉头三指针
先存nxt再反指
prev前移curr跟
闭眼写对不迟疑