大家好!我是曾续缘😁
今天是《LeetCode 热题 100》系列
发车第 31 天
链表第 10 题
❤️点赞 👍 收藏 ⭐再看,养成习惯
给你链表的头节点
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]提示:
- 链表中的节点数目为
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
进阶:你可以设计一个只用
O(1)
额外内存空间的算法解决此问题吗?难度:💝💝💝
解题方法
这道题目是要求将链表中每 k 个节点进行翻转。如果节点总数不是 k 的整数倍,那么最后剩余的节点保持原有顺序。
我们可以使用迭代的方式来处理。首先创建一个虚拟头节点 dummy,并将其指向链表的头节点 head。同时定义两个指针 pre 和 end,它们的初始值都指向 dummy。
然后通过遍历链表来确定每一组的起始节点和结束节点。对于每一组,我们需要将其中的节点进行翻转,这可以借助之前做过的题目反转链表的函数。具体步骤如下:
- 移动 end 指针,直到它指向当前组的最后一个节点,或者到达链表末尾。
- 如果 end 指针为空,说明剩余的节点数量不足 k 个,直接返回结果。
- 否则,记录当前组的起始节点 begin 和下一组的起始节点 subList。
- 将当前组的结束节点 end 的 next 指针置空,断开当前组与下一组的连接。
- 使用反转链表的函数将当前组的起始节点 begin 进行翻转,得到新的头节点 newHead返回。
- 将翻转后的链表连接回原来的位置,即将 pre 的 next 指针指向返回的 newHead,将 begin 的 next 指针指向 subList。
- 更新 pre 和 end 指针,使它们指向下一组的起始节点的前一个节点。
最后返回虚拟头节点 dummy 的 next 指针,即为翻转后的链表。

Code
查看代码
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
ListNode pre = dummy, end = dummy;
while(end.next != null){
for(int i = 0; i < k; i++){
end = end.next;
if(end == null){
return dummy.next;
}
}
ListNode begin = pre.next, subList = end.next;
end.next = null;
pre.next = reverseList(begin);
begin.next = subList;
pre = begin;
end = begin;
}
return dummy.next;
}
public ListNode reverseList(ListNode head) { // 反转链表
if (head == null || head.next == null) {
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}