题目描述
今天看一道链表里最基础、也最值得反复回顾的题:反转链表。
这题本身不复杂,但它是很多链表题的底层动作。像 K 个一组翻转、局部翻转、回文链表,最后都会回到这套指针调整逻辑。
这是一道典型的链表指针模板题。
题意理解
给你一条单链表,要求把整条链表的指向完全反过来,并返回新的头节点。
比如原链表是 1 -> 2 -> 3 -> 4 -> 5,反转后就会变成 5 -> 4 -> 3 -> 2 -> 1。
一句话概括:
把链表中每个节点的 next 指针方向全部翻转过来。
题目考查点
数据结构:链表
算法思想:迭代、指针重连
重点能力:如何在修改指针时不丢失后续节点
容易出错的地方:改了当前节点的
next后,忘了提前保存后继节点
💻 算法 Code
class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; }}当前Java语言示例,更多语言请打开页面查看。
🎬 算法动画
动画讲解请看网站演示:网页链接 https://algo.lifestudylab.com/problems/reverse-linked-list
🧠 核心实现思路
先说结论:这题最常用的写法就是三个指针迭代推进。
1. 为什么这题看起来简单却容易写错?
因为链表没有下标,所有关系都靠指针维持。
一旦你把当前节点的 next 改掉,却没有提前存下后继节点,后面的链就断了。
2. 三个指针分别做什么?
prev:表示当前节点反转后要指向的前一个节点curr:当前正在处理的节点next:提前保存原链表里的下一个节点
3. 每一轮到底做哪三步?
每次循环都固定做下面三件事:
先保存
next = curr.next再把
curr.next = prev最后整体前进:
prev = curr,curr = next
这样既不会丢链,也能把方向逐步翻过来。
4. 为什么最后返回 prev?
因为循环结束时,curr 已经走到 null 了。
此时 prev 正好停在原链表最后一个节点,也就是反转后新的头节点。
5. 复杂度是多少?
时间复杂度:
O(n)空间复杂度:
O(1)
🎯 面试时忘记怎么办?
第一步:先说大方向
“我会用迭代做,核心是边遍历边改当前节点的 next 指向。”
第二步:再说关键动作
“为了不丢链,我会先保存后继节点,然后把当前节点反指向前一个节点,最后三个指针一起前进。”
第三步:最后补复杂度
“链表只遍历一次,所以时间复杂度 O(n),只用了常数级额外变量。”
最后一定要点出关键点
先存后继,再改指针,这是所有链表翻转题最核心的动作。
这道题最值得记住的一句话:
链表翻转的本质,就是安全地把每个节点的 next 指回前驱。
完整动画请点击左下角「阅读原文」。
夜雨聆风