原題
簡介
該題共有2種解法,一種迭代,一種遞歸。
迭代法
解題思路
每一次取K個節點作爲子鏈表,將其反轉,然後將反轉後的子鏈表添加到新的鏈表中。
圖解
代碼
public class Solution25 {
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null || head.next == null || k <= 1)
return head;
ListNode first, second, third;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode subHead = head, subTail, oldSubTail = dummy, nextSubHead;
do {
subTail = findSubTail(subHead ,k);
if (subTail == null)
break;
else
nextSubHead = subTail.next;
reverseSubList(subHead, subTail);
//更新標誌位的值
oldSubTail.next = subTail;
oldSubTail = subHead;
subHead = nextSubHead;
}while (true);
oldSubTail.next = subHead;
return dummy.next;
}
private void reverseSubList(ListNode subHead, ListNode subTail) {
ListNode first = subHead;
ListNode second = first.next;
first.next = null;
while (first != subTail){
ListNode third = (second == null) ? second : second.next;
second.next = first;
first = second;
second = third;
}
}
private ListNode findSubTail(ListNode subHead, int k) {
ListNode subTail = subHead;
for (int i = 1; i < k; i++) {
subTail = (subTail == null) ? null : subTail.next;
}
return subTail;
}
}
遞歸法
解題思路
Ⅰ、找到第K+1個節點,作爲頭節點遞歸,返回遞歸後的頭節點curr;
Ⅱ、反轉前K個節點並連接到curr;
代碼
請參見:遞歸法
public ListNode reverseKGroup(ListNode head, int k) {
ListNode curr = head;
int count = 0;
while (curr != null && count != k) { // find the k+1 node
curr = curr.next;
count++;
}
if (count == k) { // if k+1 node is found
curr = reverseKGroup(curr, k); // reverse list with k+1 node as head
// head - head-pointer to direct part,
// curr - head-pointer to reversed part;
while (count-- > 0) { // reverse current k-group:
ListNode tmp = head.next; // tmp - next head in direct part
head.next = curr; // preappending "direct" head to the reversed list
curr = head; // move head of reversed part to a new node
head = tmp; // move "direct" head to the next node in direct part
}
head = curr;
}
return head;
}