題目描述
給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例:
給你這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明:
你的算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
白話題目:
一個單鏈表,一個整數,把鏈表按照k個一組分組翻轉。不夠k個的原樣輸出
算法:
另闢蹊徑,或者是好的思路勝過千言萬語和聰明的頭腦。不要陷入先一個題,2個階段互換的坑,要爬出來啊,兄弟姐妹們,奧利給。
頭插法實現鏈表的翻轉
請記住羅馬不是一天建成的。每一個複雜的代碼都是由不同的功能累加而成的。
(1)尾插法建鏈表
(2)新建一個鏈表的頭結點
(3)檢查鏈表是否能形成k個分組,不行的話就趕快結束
for(i=0; i<k-1; i++) //先判斷,後頭插,移動k-1個
{
if(current==NULL)
{
break; //break防止再next沒有值
}
current=current->next;
}
(4)提前結束的就要特殊處理了。。。。。。
(5)k個一堆的【頭插】入剛纔的新鏈表中
(6)鏈表就是玩指針呀,要會玩,一點點的嘗試,使後面的按照前面的規律操作。
(7)新鏈表頭插一組後,也得調整標識啊
(8)不滿足條件的那些直接連上
利用first的指針,pre指針指向first,pre再往後準備下一要被連的位置,firsrt往後挪
while(first)
{
pre->next=first;
pre=pre->next;
first=first->next;
}
(9)返回新鏈表頭節點的下一個,形成無頭鏈表地址
(10)輸出
詳細解釋關注 B站 【C語言全代碼】學渣帶你刷Leetcode 不走丟 https://www.bilibili.com/video/BV1C7411y7gB
C語言完全代碼
#include <stdio.h>
#include <stdlib.h>
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode
{
int val;
struct ListNode *next;
} ListNode;
ListNode *ListCreate(int n)
{
ListNode *p=NULL,*head,*r;
head=NULL;
r=head;
int i=0;
//尾插法
while(i<n)
{
int x;
scanf("%d",&x);
p=(ListNode*)malloc(sizeof(ListNode));
p->val=x;
if(head==NULL) //第一個
{
head=p;
r=p;
p->next=NULL;
}
else
{
r->next=p;
r=p;
}
i++;
}
r->next=NULL;
return head;
}
void ListPrint(struct ListNode *head)
{
ListNode *p;
p=head;
while(p!=NULL)
{
printf("%d ",p->val);
p=p->next;
}
printf("\n");
}
struct ListNode* reverseKGroup(struct ListNode* head, int k)
{
struct ListNode *NewHead = (struct ListNode*)malloc(sizeof(struct ListNode));
NewHead->next = NULL; //弄個頭
struct ListNode *pre=NewHead;
struct ListNode *first = head;
struct ListNode *next = first->next; //也可以說是second
struct ListNode *current = head;
while(1)
{
int i=0;
for(i=0; i<k-1; i++) //先判斷,後頭插,移動k-1個
{
if(current==NULL)
{
break; //break防止再next沒有值
}
current=current->next;
}
if(current == NULL) //要是爲空的完事了這個循環,走直接連接的步驟
{
break;
}
for(i=0; i<k; i++) //頭插插入三個
{
next=first->next;
first->next=pre->next;
pre->next=first;
first=next;
}
//插完之後,頭插法的pre得動彈k個
for(i=0; i<k; i++)
{
pre=pre->next;
}
current=next; //first也指向下一組的開始,
}
while(first)
{
pre->next=first;
pre=pre->next;
first=first->next;
}
pre->next=NULL;
return NewHead->next;
}
int main()
{
int k;
printf("請輸入幾步一分組\n");
scanf("%d",&k);
int n;
printf("請輸入鏈表元素個數\n");
scanf("%d",&n);
ListNode * head=ListCreate(n);
ListNode * result=reverseKGroup(head, k);
ListPrint(result);
return 0;
}