双指针法
核心思想: “框出”k个结点为一组进行单链表的局部翻转,不足k个结点,则保持原有顺序
/**
* 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 resList = new ListNode(0, head);//结果链表的理论头结点
ListNode start = resList;//一组的相邻前一个结点,用于头插法
ListNode end = resList;//一组中的最后一个结点
ListNode endTemp = start;//标记下一组的相邻前一个结点
int count = 0;//计数器
while(end != null){
if(count == k){//“框出”k个结点为一组进行单链表的局部翻转
endTemp = start.next;
groupReverse(start, end);//单链表的局部翻转
}
else{
end = end.next;
count++;
continue;
}
start = endTemp;//start指向下一组的相邻前一个结点,进行下一组迭代
end = endTemp;//end指向下一组的相邻前一个结点,进行下一组迭代
count = 0;//计数器复原,进行下一组迭代
}
return resList.next;
}
//利用头插法实现单链表翻转
public void groupReverse(ListNode start, ListNode end){
ListNode finish = end.next;//用于记录局部单链表的边界,“相当于null”
ListNode cur = start.next;//当前待插入的结点
start.next = finish;
while(cur != finish){
ListNode temp = cur.next;
cur.next = start.next;
start.next = cur;
cur = temp;
}
}
}