第4章|链表
Unit 03 · LeetCode #92 反转链表 II
局部反转不是把 Unit 02 再做一次,
而是反转过程中还要守住区间两侧。
完整反转只需维护“已反转区”和“未处理区”。局部反转还多出左侧固定前缀与右侧未动后缀;任何一次改边都必须保证它们仍能接回结果链。
题目要求
给定单链表头节点 head 和两个整数 left、right,反转位置从 left 到 right 的节点,并返回修改后的链表。
输入、输出与约束
- 节点数
1 ≤ n ≤ 500,节点值在[-500, 500]。 1 ≤ left ≤ right ≤ n。- 进阶目标:一趟扫描完成,时间
O(n),额外空间O(1)。
示例
输出:[1,4,3,2,5]
输出:[5]
本页主方法
使用 dummy + before + current + moving 的区间头插法。每次把 current 后面的一个节点摘下,插到 before 后面。
先连接上一题:#206 的三指针 Skill 仍在,但目标从“反转全部边”变为“移动局部节点”
current.next = previous
每轮改变当前节点出边方向,最后返回 previous。
moving = current.next
摘下 moving,插到 before 后;current 始终是区间尾。
稳定的虚拟前驱。即使 left=1,反转区间前仍然存在 before,避免单独处理头节点。
反转区间前一个节点。整个头插过程保持不动,before.next 始终指向当前区间头。
原区间第一个节点。头插过程中它不前移,而是逐渐成为当前已反转区间的尾节点。
current.next 指向的节点。本轮先把它从原位置摘下,再插到 before 后面。
left=1 时找不到稳定前驱,必须额外修改 head,代码边界分支膨胀。
current 应保持为当前区间尾;前移会跳过尚未搬到区间头的节点。
需要移动 right-left 个节点。多一次会把区间外的第一个节点也拖入反转区。
当前执行状态
迁移题:LeetCode #24 两两交换链表中的节点
#92 教会我们在局部范围内安全地“摘下后继并插到前面”。#24 把区间长度固定为 2,并要求对整条链表重复执行这一局部重连。迁移重点是:保留改边结构,同时重新定义循环边界和前驱移动规则。
完整反转:逐条改变边方向;局部反转:守住区间两侧并连续头插;两两交换:把长度为 2 的局部头插重复应用到整条链表。
LeetCode #24|两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表头节点。不能修改节点内部的值,必须真正改变节点之间的连接关系。
官方示例与约束
输出:[2,1,4,3]
输出:[]
输出:[1]
输出:[2,1,3]
- 节点数在
[0,100]范围内。 0 ≤ Node.val ≤ 100。- 最后只剩一个节点时,它保持原位置。
读题检查 1:允许交换节点值吗?
读题检查 2:输入 [1,2,3] 的结果是什么?
#92 与 #24:同一个局部改边模板,不同的调度方式
| 维度 | #92 反转链表 II | #24 两两交换 |
|---|---|---|
| 处理范围 | 只处理位置 [left,right] | 从头到尾处理每一对相邻节点 |
| 稳定前驱 | before 固定在整个反转区间前 | previous 每交换一对后移动到该对尾部 |
| 局部角色 | current 是区间尾,moving=current.next | first=previous.next,second=first.next |
| 改边核心 | 摘下 moving,插到 before 后 | 摘下 second,插到 previous 后 |
| 循环边界 | 固定执行 right-left 次 | 只要还存在完整的一对就继续 |
| 尾部处理 | 区间右侧始终由 current.next 接回 | 奇数长度时最后一个节点保持原位 |
before→current→moving→following 经过重连变为 before→moving→current→following。在 #24 中只需重命名为 previous→first→second→following。结构检查:交换完成后 previous 移到哪里?
循环检查:为什么需要两个非空条件?
把旧结构映射成 #24 的四个语义槽位
创建 dummy,并让 previous 从 dummy 开始。
从 previous 后面取得 first 与 second。
先保存 following,再构造 previous→second→first→following。
previous 移到这一对的尾部,最后返回真实头节点。
官方样例轨迹:head = [1,2,3,4]
不要复制左侧轨迹。独立写出迭代解法,检查器只验证关键结构。
Unit 03 Skill 卡
触发信号:只反转链表中的连续区间。核心表示:dummy / before / current / moving。核心不变量:before.next 是区间头,current 是区间尾。核心操作:摘下 current.next,插到 before 后。复杂度:O(n) 时间、O(1) 额外空间。
完成后可以停留、回看任意阶段;只有你主动点击时才进入 Unit 04。