简单LeetCode 206可逐步演示引导学习
反转链表
双指针边走边反转
用 prev 和 cur 两个指针边走边反转:每步把 cur.next 指向 prev,然后两个指针各前进一格——一趟走完,整条链表就地反转。
时间复杂度 O(n)空间复杂度 O(1)
题单:面试热题
题目描述
给定单链表的头节点 head,把整条链表反转,返回反转后的新头节点。例如 1 → 2 → 3 → 4 → 5 要变成 5 → 4 → 3 → 2 → 1。
学习目标
能说清反转链表为什么必须先用 nxt 保存后继,并能按顺序写对 prev / cur / nxt 三个指针的推进。
已完成 0 / 6 阶段
诊断
先看:为什么不能直接改 cur.next
如果拿到一个节点 cur,直接执行 cur.next = prev,会丢失什么?为什么必须先保存 nxt?
反转链表时,修改 cur.next 之前必须先做什么?
建议先完成当前阶段(提示 / 检查 / 自评),再进入下一步;也可以直接跳过。
解题思路
核心思想
用 prev 和 cur 两个指针边走边反转:每步把 cur.next 指向 prev,然后两个指针各前进一格——一趟走完,整条链表就地反转。
为什么需要它
反转的难点是"改指向会断链":一旦把 cur.next 指向 prev,原来的链就断了,找不回下一个节点。所以整个过程必须按固定节奏走:先存 nxt,再改 cur.next,再前进。
第一反应:直觉方案
把链表的所有节点先倒进一个数组,再倒着把节点一个一个重新连起来。能出答案,但要额外 O(n) 的空间,重连的细节也更啰嗦。
关键洞察
关键洞察是"断链只是视角问题":你不需要同时握住整条链表,只需要保证每次操作时手上有三个位置——prev(已反转部分的头)、cur(当前节点)、nxt(未处理部分的头)。只要先把 nxt 收好,改掉 cur.next 就是安全的;三个指针像拉链一样推进,链表的"断点"永远位于已处理区和未处理区之间。
时间复杂度 O(n)空间复杂度 O(1)
易错点
- 必须先保存 nxt 再改 cur.next——顺序反了会断链丢节点
- 循环条件是 while cur(cur 为空时停),写成 while cur.next 会漏掉最后一个节点
- 返回 prev 而不是 head——head 已经变成尾节点
逐步演示
参考代码
1function reverseList(head) {
2 let prev = null;
3 let cur = head;
4 while (cur) {
5 const nxt = cur.next;
6 cur.next = prev;
7 prev = cur;
8 cur = nxt;
9 }
10 return prev;
11}
效果图
预测:答对 0 / 共 1 题
第 1 / 23 步