題目
給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例:
給你這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
思路
題意就是將鏈表分組,以組爲單位進行反轉。
首先先理解下反轉鏈表的實現,就是1->2->3 變成 1<-2<-3,就是把箭頭調換一下。參與下面代碼理解。
理解完反轉代碼後,我們現在針對此題目就是要加一個條件,分段來,以k個爲一個組,那我們就是count 計算下,遍歷到k個就把range 爲start ~ tail 部分當前一個小鏈表進行反轉。
看下面代碼吧!
ps: 鏈表反轉()
public ListNode reverse (ListNode head) {
if(head == null) return head;
// head 就是我
ListNode pre = null; // 在我前面的節點,初始化時,因爲第一個節點反轉後 要變成最後一個節點,最後一個節點的標誌就是next 爲null,所以讓我的頭節點爲null.等會就會接在我後面啦。
while(head!=null) { // 結束條件: 是不是到底了 (head 就是當前的節點)
ListNode next = head.next; // 因爲要調轉箭頭指向了嘛,也就是原來的接在我後面的節點將不是這個head.next,要轉交到別人手上了,所以保存下,別弄丟了,爲什麼要保存?劇透下,head.next 就是下一個要反轉的對象
head.next = pre; // 把原先在我前面的節點變成我的下一個節點,箭頭就換了吖。
pre = head;//當前節點的交換任務已經完成,我就要變成過去啦,所以給pre
head = next;// 開始下一個節點的操作,而這個下一個節點就是剛next 暫存的值
}
return pre;
}
解法
class Solution {
public ListNode reverseKGroup (ListNode head, int k) {
ListNode dummy = new ListNode(0); // 哨兵,爲了不想特殊處理頭節點,頭節點和別人不一樣,沒有前驅節點,所以給個假頭,後面就可以統一方法處理,很多鏈表題都是這種寫法
dummy.next = head;
ListNode pre = dummy;
ListNode tail = dummy;
while (true) {
int count = 0;
while (tail != null && count != k) { // 計算count,一旦找到等於k這個機會,就進行反轉
count++;
tail = tail.next;
}
if (tail == null) break; // 退出條件
ListNode head1 = pre.next;
while (pre.next!=tail){ // 反轉的結束條件: 是不是到底了,也就是我是不是等於尾節點了
ListNode cur = pre.next;
pre.next = cur.next;
cur.next = tail.next;
tail.next = cur;
}
pre = head1; //新的起點,準備開始新一輪計算,反轉
tail = head1;
}
return dummy.next;
}
}