K 个一组翻转链表
2024年8月30日约 420 字大约 1 分钟
K 个一组翻转链表
题意
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
思路
输入 head
,reverseKGroup()
能够把以 head
为头的这条链表进行翻转。
我们要充分利用这个递归函数的定义,把原问题分解成规模更小的子问题进行求解。
先反转以
head
开头的k
个元素将第
k + 1
个元素作为head
递归调用reverseKGroup()
将上述两个过程的结果连接起来,返回头结点即可
代码
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null) return null;
// 区间 [a, b) 包含 k 个待反转元素
ListNode a, b;
a = b = head;
for (int i = 0; i < k; i++) {
// 不足 k 个,不需要反转
if (b == null) return head;
b = b.next;
}
// 反转前 k 个元素
ListNode newHead = reverse(a, b);
// 递归反转后续链表并连接起来
a.next = reverseKGroup(b, k);
return newHead;
}
// 反转区间 [a, b) 的元素,注意是左闭右开
ListNode reverse(ListNode a, ListNode b) {
ListNode pre, cur, nxt;
pre = null;
cur = a;
nxt = a;
// while 终止的条件改一下
while (cur != b) {
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
// 返回反转后的头结点
return pre;
}
}