思路
- 首先定义两个函数分别是,从start位置开始,返回之后的第k个节点 和 从start开始,到end反转,然后将反转后的尾节点连接到之后的链表
- 然后在主函数中,进行具体的操作逻辑;将函数k个一组进行反转,然后尾节点连接到之后的节点,用一个lastEnd节点记录这次的尾节点,然后循环往复,每次将lastEnd连接到下一个反转后链表的头部,保持反转后相连
画图解释:
代码实现(java)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode start = head;
ListNode end = getGroupEnd(head, k);
if(end == null) return head;
head = end;
reserve(start, end);
ListNode lastEnd = start;
while(lastEnd.next != null) {
start = lastEnd.next;
end = getGroupEnd(start, k);
if(end == null) return head;
reserve(start, end);
lastEnd.next = end;
lastEnd = start;
}
return head;
}
// 返回k个一组的最后一个元素,如果不够K个元素,则返回null
public ListNode getGroupEnd(ListNode start, int k) {
while(--k != 0 && start != null) {
start = start.next;
}
return start;
}
// 反转指定链表,并将反转后的链表尾部,连接到下一段
public void reserve(ListNode start, ListNode end) {
end = end.next;
ListNode pre = null;
ListNode next = null;
ListNode cur = start;
// 这里重点注意,不是cur != null 而是 cur != end
// 因为反转的是一个区间,末尾不一定就是null
// 类比的,将end 看作为 null,之后就和普通的反转链表一样了
while(cur != end) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
start.next = end;
}
}