第4章|链表
Unit 04 · 两两交换:固定长度局部重写
交换的不是两个数值,
而是三条连接关系。
每轮只处理相邻两个节点:先保存这一对之后的入口,再把 previous → first → second → following 改写为 previous → second → first → following。节点对象没有被复制,也没有交换 val。
题目要求
给定一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。必须通过修改节点之间的连接完成,不能只交换节点中的数值。
约束与复杂度目标
- 节点数量范围为
[0, 100];节点值范围为[0, 100]; - 奇数长度链表的最后一个节点保持原位;
- 迭代解法时间复杂度
O(n),额外空间O(1)。
示例
输出:[2,1,4,3]
输出:[]
输出:[1]
输出:[2,1,3]
本页主模型
使用 dummy + previous 固定已完成区域的尾部。每轮获取 first、second 和 following,安全改写三条边。
连接上一题:#92 的“局部头插”缩小为长度固定为 2 的局部改写
moving = current.next
把 moving 不断插到 before 后面,循环次数由区间长度决定。
second = first.next
每组只做一次“第二个节点移到第一个节点之前”。
已完成交换区域的最后一个节点。它提供下一组节点的稳定前驱,初始为 dummy。
当前一对中的第一个节点,即 previous.next。交换后成为这一对的尾节点。
当前一对中的第二个节点,即 first.next。交换后成为这一对的头节点。
当前一对后面的第一个节点,即 second.next。必须先保证它仍能被 first 连接。
此时 first.next 仍指向 second,会立即形成 first ↔ second 的二节点环。
second 是交换后这一对的头,不是尾。下一轮会从 first 开始,把已处理节点再次纳入。
奇数尾节点可能存在 first,但不存在 second;继续读取 first.next 的字段会破坏边界契约。
当前执行状态
迁移原题:LeetCode #25 K 个一组翻转链表
先完整理解原题,再迁移局部重写。#24 是固定两节点的一次交换;#25 需要先确认剩余节点足够组成完整 K 组,再反转整组并接回主链。
给定链表头节点 head,每 k 个节点一组进行翻转并返回修改后的链表。若最后剩余节点不足 k 个,它们必须保持原有顺序。不能只修改节点值,必须实际改变节点连接。
class Solution:
def reverseKGroup(
self,
head: Optional[ListNode],
k: int
) -> Optional[ListNode]:
pass
官方示例与约束
输出:[2,1,4,3,5]
输出:[3,2,1,4,5]
1 ≤ k ≤ n ≤ 50000 ≤ Node.val ≤ 1000- 最后不足
k个节点保持原顺序。 - 进阶:使用
O(1)额外空间。
读题门槛
[1,2,3,4,5]、k=3,节点 4、5 应如何处理?
#24 → #25:不变的是组级契约,新增的是完整组检查
| 维度 | #24 两两交换 | #25 K 个一组 |
|---|---|---|
| 组大小 | 固定为 2 | 由输入 k 决定 |
| 组前驱 | previous | group_prev |
| 完整组判断 | 检查 first、second | 从 group_prev 向后找到 kth |
| 组后入口 | following | group_next = kth.next |
| 组内操作 | 三条边交换两个节点 | 标准反转区间 [组首, group_next) |
| 下一组前驱 | 原 first | 原组首 group_tail |
排列一整组的安全处理顺序
点击卡片。只有先确认完整组并保存右边界,才可以开始修改组内连接。
语义槽位:先完成状态契约,再看组装代码
kth = get_kth(group_prev, k)
if kth is None:
break
group_next = kth.next
previous = group_next
current = group_prev.next
while current is not group_next:
next_node = current.next
current.next = previous
previous = current
current = next_node
group_tail = group_prev.next
group_prev.next = kth
group_prev = group_tail
官方样例轨迹:[1,2,3,4,5],k=3
独立重写:不提供完整答案填充
Unit 04 Skill 卡
当题目要求按固定大小重写局部链表时,不要让节点“整体跳位置”掩盖改边过程。先命名局部角色,再按安全顺序修改每条边。