LeetCode[25].K个一组翻转链表

Note(1)在写翻转函数时,把pre 初始化成 tail 的下一个节点,则反转后链表的尾节点(原来的头结点)可>以直接和长(总)链表链接,无需额外处理 若初始化为 null 则相当于链表会断开 此时直接将上一个链表的尾部和反转后链表的头部链接即可完成反转
(2)翻转函数中的while 循环不同于leetcode25 中的翻转链表可以用
cur != null
当终止条件(因为后面还有链表) 只能用pre != tail
来终止(3)虚拟头节点在第一次遍历 k 时能够简化操作保证和后面遍历 k 的操作一样,否则第一次会少一次(因为遍历是以上一个链表的尾部为基准往后数 k 个),此时的虚拟节点就相当于上一个链表的尾部
(4)在遍历 K 个节点一组时,要注意判断
tail是否还有 next
没有即不足 K 个,此时直接返回虚拟节点的下一个节点
代码:
class Solution {
public ListNode[] myReverse(ListNode head,ListNode tail){
ListNode pre = tail.next; //见注解
ListNode cur = head;
//见注解
while(pre!=tail){
ListNode tem = cur.next;
cur.next = pre;
pre = cur;
cur = tem;
}
//翻转后的头部即原尾部,翻转后的尾部即原头部
return new ListNode[]{tail,head};
}
public ListNode reverseKGroup(ListNode head, int k) {
//有虚拟头节点在第一次遍历 k 时能够简化操作保证和后面遍历 k 的操作一样,否则第一次会少一次(因为遍历是以上一个链表的尾部为基准往后数 k 个)
ListNode dum = new ListNode();
dum.next = head;
//上一个链表的尾部
ListNode pre = dum;
while(pre != null){
ListNode tail = pre;
for(int i = 0;i<k;i++){
//特判
if(tail.next!=null) tail = tail.next;
else return dum.next;
}
ListNode[] result = myReverse(pre.next,tail);
pre.next = result[0];
pre = result[1];
}
return dum.next;
}
}