學渣帶你刷Leetcode0025.K個一組翻轉鏈表

題目描述

給你一個鏈表,每 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章