问题核心含义:K 个一组翻转链表
1. 官方定义(严格版)
以 k 个节点为一个分组,对链表的每一组进行完整反转;若链表剩余节点数量不足 k 个,则保持原有顺序不翻转。
2. 直观示例
输入链表:1 -> 2 -> 3 -> 4 -> 5,k = 3
- 第一组:
1、2、3(满足 3 个节点)→ 翻转 →3 -> 2 -> 1 - 第二组:
4、5(不足 3 个节点)→ 不翻转 - 最终输出:
3 -> 2 -> 1 -> 4 -> 5
3. 可视化流程图
原链表:1->2->3->4->5 分组 k=3 第一组:1,2,3 第二组:4,5 翻转后:3->2->1 不翻转:4->5 最终链表:3->2->1->4->5 图表说明:清晰展示了「分组→判断长度→分组翻转→拼接结果」的全流程,不足 k 个的分组直接保留原序。
算法原理:基于「reverse N」的分层实现
本题的核心解题思路是拆分法:将「K 组翻转」拆解为两个基础能力的组合——
- reverse N 计数判断:检查当前链表是否有足够的 N 个节点供翻转;
- __reverse N 私有翻转:真正实现「翻转链表前 N 个节点」的核心逻辑。 这是官方推荐的最优解思路,无冗余操作,时间复杂度趋近于 O(n)。
1. 基础能力:reverse N 节点计数判断
作用:前置校验,避免对不足 k 个节点的分组执行翻转。 实现逻辑:
- 定义指针 p 指向当前分组的头节点;
- 循环递减 k,同时让 p 向后遍历;
- 若循环结束后 p 不为空 → 剩余节点 ≥k,可翻转;
- 若 p 为空 → 剩余节点 <k,终止翻转。
2. 核心能力:__reverse N 前 N 个节点翻转
这是真正执行翻转的私有函数,严格遵循题目指定逻辑:
- 递归终止条件:n == 1,直接返回当前头节点(最后一个节点是新头);
- 定义 tail:指向 head->next(原分组头节点,翻转后成为分组尾节点);
- 定义 newHead:递归翻转后的新头节点;
- 最终返回 newHead(翻转后分组的头节点)。
整体实现框架:虚拟头节点 + 双指针循环
链表翻转的最大坑点是头节点会变化,因此必须使用虚拟头节点技巧破局;同时通过双指针记录关键位置,保证分组拼接不断裂。
1. 核心技巧:虚拟头节点
创建一个虚拟节点 dummy,让 dummy->next = 原链表头节点。 作用:无论链表头节点如何翻转,最终直接返回 dummy->next 即可,彻底解决头节点边界问题。
2. 关键位置指针定义
我们定义两个核心指针,这是循环翻转的关键:
| 指针名称 | 核心作用 | 位置变化 |
|---|---|---|
| p | 待翻转区域的前驱节点 | 始终指向当前分组的前一个节点,初始指向虚拟头 |
| q | 待翻转区域的头节点 / 翻转后的尾节点 | 初始 = p->next,翻转后成为当前分组的尾节点,是下一次的 p |
3. 循环翻转逻辑
- 以 reverseN(q, k) 为循环条件(返回非空说明可翻转);
- 执行翻转,将前驱节点 p 与新头节点拼接;
- 指针后移:p = q(当前分组尾 → 下一组前驱),q = p->next(下一组头);
- 直到 reverseN 返回空,循环结束。


