思路:
先将整体链表反转:0,1,2,3,4,5,6,7 ==> 7,6,5,4,3,2,1,0
再从链表头以K个节点为一组反转:5,6,7,4,3,2,1,0 -> 5,6,7,2,3,4,1,0
再进行整体反转得到 0,1,4,3,2,7,6,5
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
public class Solution {
public ListNode reverseKFromEnd(ListNode head, int k) {
if (head == null || k <= 1) {
return head;
}
// 先整体反转链表
ListNode reversedHead = reverseList(head);
printfNode(reversedHead, "first");
// 从头开始每K个一组反转
ListNode newHead = null;
ListNode prevTail = null;
ListNode current = reversedHead;
while (current != null) {
ListNode groupHead = current;
ListNode groupTail = current;
// 找到当前组的尾节点
for (int i = 1; i < k && groupTail != null; i++) {
groupTail = groupTail.next;
}
// 如果当前组长度小于K,则无需反转,直接跳出循环
if (groupTail == null) {
break;
}
// 记录下一组的起始节点
ListNode nextGroupHead = groupTail.next;
// 反转当前组
ListNode prev = nextGroupHead;
ListNode currentGroupNode = groupHead;
while (currentGroupNode != nextGroupHead) {
ListNode nextNode = currentGroupNode.next;
currentGroupNode.next = prev;
prev = currentGroupNode;
currentGroupNode = nextNode;
}
//56743210 groupTail=5, nextGroupHead=4
// 将反转后的组接到结果链表上
if (prevTail != null) {
prevTail.next = groupTail;
} else {
newHead = groupTail;
}
// 更新prevTail,准备连接下一组,目前反转后7节点作为表头连接到4节点上,当下一组再反转完成后,
// 7节点则需要连接到2节点上,这里作为保存在prevTail,下次使用prevTail.next = groupTail 连接
prevTail = groupHead;
// 将current指向下一组的起始节点
current = nextGroupHead;
}
// 再次整体反转链表
return reverseList(newHead);
}
// 反转链表
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode current = head;
while (current != null) {
ListNode nextNode = current.next;
current.next = prev;
prev = current;
current = nextNode;
}
return prev;
}
public void printfNode(ListNode head, String logTag){
String nodeStr = "";
while (head != null){
nodeStr += head.val+",";
head = head.next;
}
System.out.println(logTag+" nodeStr: "+nodeStr);
}
}