目录
题目
- 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
法一、模拟--迭代
- 遍历列表,到达计数k将k个用头插法翻转,注意翻转后连接回整个链表。没有达到k不进行翻转
var reverseKGroup = function(head, k) {
// 创建一个虚拟节点,以简化边界条件处理
let dummy = new ListNode();
dummy.next = head; // 将虚拟节点的next指向原链表的头节点
let [start, end] = [dummy, dummy.next]; // start指向虚拟节点,end指向链表的第一个节点
let count = 0; // 计数器,用于计数节点
// 遍历链表,直到end为null
while(end) {
count++; // 计数节点数量
// 当计数到k的倍数时,表示需要进行翻转
if (count % k === 0) {
// 翻转start到end之间的链表
start = reverseList(start, end.next);
end = start.next; // 更新end为翻转后的链表的下一个节点
} else {
end = end.next; // 移动end指针
}
}
return dummy.next; // 返回翻转后的链表头节点,即dummy.next
// 翻转start到end之间的链表
function reverseList(start, end) {
let [pre, cur] = [start, start.next]; // pre指向start,cur指向start的下一个节点
const first = cur; // 记录翻转后的第一个节点
// 头插法进行翻转,直到cur等于end
while(cur !== end) {
let next = cur.next; // 记录cur的下一个节点
cur.next = pre; // 将cur的next指向pre,实现翻转
pre = cur; // 移动pre到cur
cur = next; // 移动cur到下一个节点
}
// 将翻转后的子链表连接前后
start.next = pre; // 将start的next指向翻转后的第一个节点
first.next = cur; // 将翻转后的第一个节点的next指向end(即cur)
return first; // first经过翻转应该在子链表最后
}
};
法二、递归
var reverseKGroup = function(head, k) {
let cur = head;
let count = 0;
// 求k个待反转元素的首节点和尾节点
while(cur != null && count != k){
cur = cur.next;
count++;
}
// 足够k个节点,去反转
if(count == k){
// 递归链接后续k个反转的链表头节点
cur = reverseKGroup(cur,k);
while(count != 0){
count--;
// 反转链表
let tmp = head.next;
head.next = cur;
cur = head;
head = tmp;
}
head = cur;
}
return head;
};
标签:25,end,cur,next,链表,节点,翻转
From: https://www.cnblogs.com/lushuang55/p/18653210