アイデア:
1)ヘッドノードのポインタヘアを設定します。このポインタは移動せず、最後にリンクリストに戻るために使用されます。
2)最初のノードの前のノードであるヘアにすべて配置されるプリポインタとエンドポインタを設定します
preは各フリップ後の開始位置を記憶するために使用され、endは将来kノードをトラバースするために使用されます
3)各トラバーサルに開始ポインターを設定します。これは、関数に終了を渡して反転操作に使用されます。
コード:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode hair=new ListNode(0);
hair.next=head;
ListNode pre=hair;
ListNode end=hair;
while(end.next!=null){
for(int i=0;i<k&&end!=null;i++){
end=end.next;
}
//以下条件不可忽略
if(end==null) break;
ListNode start=pre.next;
ListNode next=end.next;
//此处的目的是调用reverse函数时,使得start后面的节点只有2个(包括子函数)
end.next=null;
//翻转后的链表与原先的重新接上
pre.next=reverse(start);
start.next = next;
pre = start;
end = pre;
}
return hair.next;
//以上一共声明了hair,pre,start,end,next五个指针
}
private ListNode reverse(ListNode start){
ListNode pre=new ListNode(0);
ListNode curr=start;
//设置空指针让start=空指针
while(curr!=null){
ListNode next=curr.next;
curr.next=pre;
pre=curr;
curr=next;
}
return pre;
}
}
壊す:
1)開始ポインターと終了ポインターは、各フリップ後に位置が入れ替わっています
2)各フリップの後、preとendが開始位置に配置されます(フリップされた開始は前の終了位置と同等です)
3)フリップ関数のコード分析