力扣——25 K个一组翻转链表
目录
1.题目描述:
2.算法分析:
3.代码展示:
1.题目描述:
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:

输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5]
示例 2:

输入:head = [1,2,3,4,5], k = 3 输出:[3,2,1,4,5]
2.算法分析:
-
计算链表长度:
- 首先遍历整个链表,统计节点的总数
n。这是为了知道有多少组k个节点需要反转。
- 首先遍历整个链表,统计节点的总数
-
初始化辅助指针:
- 使用一个虚拟头节点
dummy可以简化操作,尤其是在处理头节点的反转时。 p用于记录当前待反转子链表的前一个节点。pre和cur用于反转子链表。
- 使用一个虚拟头节点
-
分组反转:
- 只要剩余的节点数
n大于等于k,就进行反转:- 反转连续的
k个节点:- 使用类似反转单链表的方法,逐个反转节点。
- 调整连接:
- 将反转后的子链表与前面的部分连接起来。
- 将反转后的子链表的尾部与下一个子链表的头部连接。
- 移动
p到下一个待反转子链表的前一个节点。
- 反转连续的
- 只要剩余的节点数
-
处理剩余节点:
- 如果剩余的节点数不足
k,则不进行反转,直接保留原顺序。
- 如果剩余的节点数不足
-
返回结果:
- 由于
dummy的next始终指向链表的头节点,因此返回dummy->next。
- 由于
示例
假设链表为 1 -> 2 -> 3 -> 4 -> 5,k = 2:
- 计算长度
n = 5。 dummy -> 1 -> 2 -> 3 -> 4 -> 5。- 第一组反转
1和2:- 反转后:
2 -> 1,cur指向3。 - 调整连接:
dummy -> 2,1 -> 3。 p移动到1。
- 反转后:
- 第二组反转
3和4:- 反转后:
4 -> 3,cur指向5。 - 调整连接:
1 -> 4,3 -> 5。 p移动到3。
- 反转后:
- 剩余
n = 1,不足k,不反转。 - 最终链表:
2 -> 1 -> 4 -> 3 -> 5。
3.代码展示:
ListNode* reverseKGroup(ListNode* head, int k) {int n = 0; // 代表节点的个数// 计算出链表节点的个数for (ListNode* cur = head; cur; cur = cur->next) {n++;}// 创建一个空节点,便于后续的操作ListNode* dummy = new ListNode(0, head);ListNode* p = dummy;ListNode* pre = nullptr;ListNode* cur = head;for (; n >= k; n-=k) {for (int i = 0; i < k; i++) {// 进行翻转操作ListNode* nex = cur->next;cur->next = pre;pre = cur;cur = nex;}if (p->next == nullptr) {return 0;}ListNode* temp = p->next;p->next->next = cur;p->next = pre;p = temp;}return dummy->next;}
25. K 个一组翻转链表 - 力扣(LeetCode)
https://leetcode.cn/problems/reverse-nodes-in-k-group/
