題目描述
給你一個(gè)鏈表箩祥,每 k 個(gè)節(jié)點(diǎn)一組進(jìn)行翻轉(zhuǎn)院崇,請(qǐng)你返回翻轉(zhuǎn)后的鏈表。
k 是一個(gè)正整數(shù)袍祖,它的值小于或等于鏈表的長(zhǎng)度底瓣。
如果節(jié)點(diǎn)總數(shù)不是 k 的整數(shù)倍,那么請(qǐng)將最后剩余的節(jié)點(diǎn)保持原有順序蕉陋。
相關(guān)話題:?鏈表 ???難度:?困難
示例 :
給定這個(gè)鏈表:1->2->3->4->5
當(dāng) k = 2 時(shí)捐凭,應(yīng)當(dāng)返回: 2->1->4->3->5
當(dāng) k = 3 時(shí),應(yīng)當(dāng)返回: 3->2->1->4->5
說(shuō)明 :
- 你的算法只能使用常數(shù)的額外空間凳鬓。
- 你不能只是單純的改變節(jié)點(diǎn)內(nèi)部的值茁肠,而是需要實(shí)際的進(jìn)行節(jié)點(diǎn)交換。
思路:
思路很簡(jiǎn)單缩举,基本方法和反轉(zhuǎn)鏈表 II一樣垦梆。
主要是確定邊界,因?yàn)橛锌赡茏詈笫S嗟墓?jié)點(diǎn)不足k
個(gè)仅孩。
- 定義兩個(gè)指針
p
和q
托猩,p
和q
開(kāi)始都指向子區(qū)間的開(kāi)頭節(jié)點(diǎn)的前驅(qū) - 先讓
q
走k
步,如果走完k
步杠氢,q != null
則表示夠k
個(gè)站刑,否則不夠,直接結(jié)束 - 反轉(zhuǎn)完一個(gè)子區(qū)間的節(jié)點(diǎn)鼻百,更新
p
和q
的指向
/**
* 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) {
ListNode dummy = new ListNode(0);
dummy.next = head;
head = dummy;
ListNode p = head, q = p;
ListNode cur = null;
while(q != null){
//讓q先跑k步绞旅,判斷區(qū)間內(nèi)節(jié)點(diǎn)是否夠k個(gè)
for(int i = 0;i < k && q != null;i++){
q = q.next;
}
//不夠k個(gè),直接跳出
if(q == null) break;
//否則反轉(zhuǎn)子區(qū)間內(nèi)的節(jié)點(diǎn)
cur = p.next;
for(int i = 1;i < k;i++){
ListNode x = cur.next;
cur.next = x.next;
x.next = p.next;
p.next = x;
}
//開(kāi)始下一個(gè)區(qū)間
p = cur;
q = p;
}
return head.next;
}
}