题目地址
首先,链表题,都创建一个虚拟hair结点指向head,后面用不着可以删
这题如果一边翻转,一边数k个,比较麻烦。考虑先数k个,再进行翻转。
hair->1->2->3->4
1.假设k=3,数三个1,2,3。本次翻转的起始是1,记作oriSt,结束是3记作oriEd
2.翻转之前,记录起始位置的前一个pre,以及结束位置的下一个nxt
3.1,2,3进行翻转,这个是基本功,不用考虑翻转之后的头被哪个指向、尾指向哪个
4.翻完后,再接回原链表:
pre->next=oriEd;
oriSt->next=nxt;
5.进入下一次循环
class Solution {
public void reverseGroup(ListNode oriSt, ListNode oriEd){
ListNode pre = oriSt;
ListNode now = pre.next;
while(true){
ListNode nxt = now.next;
now.next=pre;
if(now==oriEd){
break;
}
pre=now;
now=nxt;
}
}
public ListNode reverseKGroup(ListNode head, int k) {
if(head.next==null || k==1){
return head;
}
ListNode hair = new ListNode();
hair.next=head;
ListNode pre = hair;//记录上一组的最后一个节点
ListNode now = pre.next;
while(true){
int cnt = 0;
while(now!=null){
cnt++;
if(cnt==k){
break;
}
now=now.next;
}
if(cnt<k){ //最后一组不足k个了,不交换
break;
}
ListNode nxt = now.next;
ListNode oriSt = pre.next;//
ListNode oriEd = now;
//翻转[st,ed]
reverseGroup(oriSt, oriEd);
//修改这段的头尾相连情况
pre.next=oriEd;
oriSt.next=nxt;
//更新
pre=oriSt;
now=pre.next;
}
return hair.next;
}
}