k个一组翻转链表
给你链表的头节点 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
代码实现:
var reverseKGroup = function(head, k) {// 检查是否有k个节点let count = 0;let curr = head;while (curr && count < k) {curr = curr.next;count++;}// 不足k个,直接返回if (count < k) return head;// 反转前k个节点let prev = null;let current = head;for (let i = 0; i < k; i++) {let next = current.next;current.next = prev;prev = current;current = next;}// 递归处理剩余部分并连接head.next = reverseKGroup(current, k);return prev;
};
1.变量含义
prev:反转后新链表的头节点
current:当前正在处理的节点
next:临时保存下一个节点,防止断链
2.检查是否有k个节点
链表: 1→2→3→4→5, k=2初始: curr=1→2→3→4→5, count=0 循环1: curr=2→3→4→5, count=1 (count<2,继续) 循环2: curr=3→4→5, count=2 (count=2,不满足count<2,停止)结果: count=2 (等于k),可以反转
3.链表翻转
head = [1,2,3]
,k = 2
为例初始:
节点1 → 节点2 → 节点3 → null ↑ ↑ current current.next prev: null第一次循环:
let next = current.next; // next: 2 → 3 → null current.next = prev; // current: 1 → null prev = current; // prev: 1 → null current = next; // current: 2 → 3 → null第二次循环:
let next = current.next; // next: 3 → null current.next = prev; // current: 2 → 1 → null prev = current; // prev: 2 → 1 → null current = next; // current: 3 → null结果:
prev: 2 → 1 → null (反转后的前2个节点)
current: 3 → null (剩余的未处理节点)
head: 1 → null (原来的头节点现在是反转组的尾节点)