/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
const l3 = new ListNode(5);
const l2 = new ListNode(4, l3);
const l = new ListNode(1, l2);
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
function myReverse(head: ListNode, tail: ListNode) {
//保存该段链表的尾节点的next指针
let prev = tail.next;
//保存该段链表的开始节点
let p: ListNode | null = head;
while (prev !== tail) {
//创建nex指针,其指向该链表的第二个节点
const nex = p!.next;
//将头节点和尾节点调换位置
p!.next = prev;
//将prev赋值为该段链表的开始节点
prev = p;
// 将该段链表的开始节点p向后移动一位
p = nex;
}
return [tail, head];
}
// 创建哨兵节点
const dummyNode = new ListNode(0);
//将哨兵节点作为头节点的直接前驱2+6
dummyNode.next = head;
// 将链表分成k段,pre将作为每一段的哨兵节点,其next始终指向该段的开始节点
let pre = dummyNode;
//注意,在此循环中head将会发生改变,其指向每一段链表的开始节点
while (head) {
//创建tail尾部指针,最终tail将指向每段链表的尾部,初始化为该段的哨兵节点
let tail: ListNode | null = pre;
for (let i = 0; i < k; i++) {
//将tail指针向后移动
tail = tail.next;
//按循环正常走完,将退出循环,tail将指向该段链表的尾元素
if (!tail) {
//如果循环中途发现tail为null,则证明该段链表的长度不足已反转,则返回整个链表的头节点,也就是哨兵节点的next指向
return dummyNode.next;
}
}
//当循环完毕,此时tail将指向该段链表的表尾元素
//创建nex指针,用于保存该段链表尾节点的后一个节点指针,以便反转后重新连接回总链表
const nex = tail.next;
//注意,此时开始结点和尾节点替换了位置
[head, tail] = myReverse(head, tail);
//将该段链表的哨兵结节 指向修改后的头节点
pre.next = head;
//将修改后的该段链表的尾节点重新指回原先的下一个节点
tail.next = nex;
//由于tail指向每段链表的尾节点,也相当于下一段链表的哨兵节点,
// 将pre 赋值为下一段链表的哨兵节点
pre = tail;
//head 赋值为下一个链表的首节点
head = tail.next;
console.log(tail, "tail");
}
//将修改后总链表的哨兵节点的next返回,其指向新链表的开始节点
return dummyNode.next;
}
console.log(reverseKGroup(l, 2));