題目:
給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例 :
給定這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
你的算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
思路:
此題爲 24. 兩兩交換鏈表中的節點 的擴展。
主要交換流程如下圖,可結合代碼查看。
注意項:需判斷當前組元素數量是否小於k(在judgeGroupLen()中),小於則直接結束。
代碼:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return null;
ListNode p,r=null,pre=null,gpre=null,gnext=null,first;
p=head;
first = head;
if(!judgeGroupLen(first,k)){
return head;
}
int i=0;
boolean flag = false; //flag表示p不是第一個該組節點
while(p!=null){
if((i<k-1)){
r = p.next;
if(flag){
p.next = pre;
}else{
flag = true;
}
pre = p;
p = r;
i++;
}else{
gnext = p.next;
p.next = pre;
//第一組,則gpre==null,取第一組的最後一個元素爲最終返回的頭節點
if(gpre!=null){
gpre.next = p;
}else{
head = p;
}
first.next = gnext;
//爲下一組數據做初始化,並判斷是否爲最後一組
i=0;
gpre = first;
first = gnext;
if(!judgeGroupLen(first,k)){
return head;
}
pre = null;
p = first;
flag = false;
}
}
return head;
}
//判斷是否是最後一組,且長度是否足夠
public static boolean judgeGroupLen(ListNode m,int k){
int i=0;
while(i<k){
if(m == null){
return false;
}
m = m.next;
i++;
}
return true;
}
}