[leetcode-連結串列]25. k個一組翻轉連結串列
給出一個連結串列,每 k 個節點一組進行翻轉,並返回翻轉後的連結串列。
k 是一個正整數,它的值小於或等於連結串列的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。
示例 :
給定這個連結串列:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
- 你的演算法只能使用常數的額外空間。
- 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
//=======================================================================
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
//處理特殊條件
if(head == NULL || head->next == NULL || k<=1)
{
return head;
}
//先找到第一組,包含k個元素,newHead指向第一組後面的第一個結點
struct ListNode *newHead = head;
int count=0;
while(newHead && count < k)
{
newHead = newHead->next;
count += 1;
}
// 1, 2, 3, 4, 5 k=2
// head newHead newHead
// temp
// ---------------->
// newHead
// head
// temp
//
//如果第一組可以找全,則進行翻轉; 反之,不需要翻轉
if(count == k)
{
//同理,處理後續元素的k組翻轉,最後返回翻轉後的頭結點newHead
newHead = reverseKGroup(newHead, k);
//對前面k個元素進行翻轉
struct ListNode *temp=NULL;
while(count > 0)
{
temp = head->next; //備份第二個結點
head->next = newHead; //兩組銜接過渡 ,第一個的下一個結點為下一組翻轉後的頭結點
newHead = head; //此時的第一個為合併資料後的部分的第一個
head = temp; //第二個為新的頭
count -= 1;
}
head = newHead;
}
return head;
}
//=======================================================================
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *reverseList(struct ListNode *head, int k)
{
struct ListNode *pnext=head;
while(pnext && k>0) //找到k個元素的下一個元素
{
pnext=pnext->next;
k--;
}
if(k>0) //不到k個元素,則無需翻轉
return head;
struct ListNode *nexthead=pnext, *pcur=head, *temp=NULL;
while(pcur != pnext) //前面k個元素以此翻轉
{
temp=pcur->next;
pcur->next = nexthead;
nexthead=pcur;
pcur=temp;
}
return nexthead;
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
if(head==NULL || head->next==NULL || k<=1)
{
return head;
}
struct ListNode dummy={.next=head}; //設定dummy首結點
struct ListNode *pcur=&dummy;
while(pcur) //從前往後以此翻轉k個元素
{
pcur->next = reverseList(pcur->next, k); //翻轉前k個元素
for(int i=0; pcur && i<k; ++i) //前進k個元素
{
pcur=pcur->next;
}
}
return dummy.next;
}