Letcode -链表问题-刷题

目录

J203-移除链表元素

J206 反转一个单链表

876. 链表的中间结点

OJ-276链表中倒数第K个节点

21. 合并两个有序链

OJ-链表插入排序

OJ-255-回文链表

OJ-160-相交链表

OJ-141给你一个链表的头节点 head ,判断链表中是否有环。

OJ-175-面试题:

OJ-142-环形链表 II

OJ-138-复制带随机指针的链表

Oj- 147-对链表进行插入排序

JZ76-删除链表中重复的结点


J203-移除链表元素

   给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

Letcode -链表问题-刷题_第1张图片

具体思路如下图所示

      通过一个prev指针和cur指针,prev负责释放cur的元素时,将prev与cur的下一个元素链接起来,next负责保存cur的下一个地址

Letcode -链表问题-刷题_第2张图片

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode*headguard=(struct ListNode*)malloc(sizeof(struct ListNode));//开辟一个哨兵位
    headguard->next=head;
    struct ListNode*prev=headguard;
    struct ListNode*cur=head;
    while(cur)//开始条件
    {
        if(cur->val==val)//迭代过程
        {
            struct ListNode*next=cur->next;
            prev->next=next;
            free(cur);
            cur=next;
        }
        else
        {
            prev=cur;
            cur=cur->next;
        }
    }
    head=headguard->next;
    free(headguard);//释放掉开辟的哨兵位
    return head;
}

 J206 反转一个单链表

 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

Letcode -链表问题-刷题_第3张图片

Letcode -链表问题-刷题_第4张图片

相当于通过创建一个newhead,然后把数据拿下来进行头插,然后进行重新置头返回新头节点.

Letcode -链表问题-刷题_第5张图片

struct ListNode* reverseList(struct ListNode* head)
{
  struct ListNode*newhead=NULL;
    struct ListNode*cur=head;
    while(cur)
    {
        struct ListNode*next=cur->next;
        cur->next=newhead;//将数据连载newhead上
        newhead=cur;     //重新置头
        cur=next; 迭代
    }
    return newhead;
}

876. 链表的中间结点

   给定一个头结点为 head 的非空单链表,返回链表的中间结点。

    如果有两个中间结点,则返回第二个中间结点。

Letcode -链表问题-刷题_第6张图片

       此题的思路在于快慢指针,快指针每次走两步,慢指针每次走一步,当快指针走到终点时,慢指针就走到了中间节点(快慢指针也可以用来作其他有固定距离的解题)

struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode*slow=head;
    struct ListNode*fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

OJ-276链表中倒数第K个节点

Letcode -链表问题-刷题_第7张图片

     此题也可以用快慢指针解决,让快指针走k步,然后快指针和慢指针一起走每次都走一步,当快指针走到最后一个节点时,此时慢指针就位要返回的节点

Letcode -链表问题-刷题_第8张图片

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k )
{
     struct ListNode*fast=pListHead;
    struct ListNode*slow=pListHead;
    while(k)
    {
        if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
        k--;
    }
    while(fast)
    {
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

21. 合并两个有序链表

Letcode -链表问题-刷题_第9张图片

Letcode -链表问题-刷题_第10张图片

       思路就是用第一个较小的节点作为新链表头节点,然后比较数据,,小的进行尾插

最后返回新链表的头即可

Letcode -链表问题-刷题_第11张图片

Letcode -链表问题-刷题_第12张图片

Letcode -链表问题-刷题_第13张图片

最后再判断一下链表一和链表二,那个还没插入完,再把没插入完的直接链接再新链表后面即可

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)

{

    if(list1==NULL)

    {

        return list2;

    }

    if(list2==NULL)

    {

        return list1;

    }

   

    struct ListNode*head=NULL;

    struct ListNode*tail=NULL;

    if(list1->valval)

    {

        head=list1;

        tail=list1;

        list1=list1->next;

    }

    else

    {

        head=list2;

        tail=list2; 

        list2=list2->next;

    }

    while(list1&&list2)

    {

        if(list1->valval)

        {

            tail->next=list1;

            list1=list1->next;

        }

        else

        {

            tail->next=list2;

            list2=list2->next;

        }

        tail=tail->next;

    }

    if(list1!=NULL)

    {

        tail->next=list1;

    }

    if(list2!=NULL)

    {

        tail->next=list2;

    }

    return head;

}

OJ-链表插入排序

描述

现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针

Letcode -链表问题-刷题_第14张图片

需要开辟两个哨兵位,来实现新链表的插入

class Partition {

public:

    ListNode* partition(ListNode* pHead, int x)

    {

        struct ListNode*smallhead,*smalltail,*bighead,*bigtail;

        smallhead=smalltail=(struct ListNode*)malloc(sizeof(struct ListNode));

        bighead=bigtail=(struct ListNode*)malloc(sizeof(struct ListNode));

        smalltail->next=NULL;

        bigtail->next=NULL;

        struct ListNode*cur=pHead;

        while(cur)

        {

            if(cur->valnext=cur;

                smalltail=smalltail->next;

            }

            else

            {

                bigtail->next=cur;

                bigtail=bigtail->next;

            }

            cur=cur->next;

        }

        smalltail->next=bighead->next;

        bigtail->next=NULL;

        pHead=smallhead->next;

        free(bighead);

        free(smallhead);

        return pHead;

    }

};

OJ-255-回文链表

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:

1->2->2->1

返回:true

思路:通过找到中间节点,中间节点后面的数据进行逆置,然后迭代从中间节点开始,与链表的中间节点前进行比较,相等输出true,否则输出false

Letcode -链表问题-刷题_第15张图片

class PalindromeList {

public:

    bool chkPalindrome(ListNode* A)

    {

        struct ListNode*slow=A;

        struct ListNode*fast=A;

        while(fast->next)

        {

            slow=slow->next;

            fast=fast->next;

        }

        struct ListNode*change=NULL;

        struct ListNode*head=slow;

        while(head)

        {

            struct ListNode*next=slow->next;

            head->next=change;

            change=head;//重新置头

            head=next;

        }

        while(slow)

        {

            if(A->val!=change->val)

            {

                return false;

            }

            slow=slow->next;

            change=change->next;

        }

        return true;

    }

};

OJ-160-相交链表

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

图示两个链表在节点 c1 开始相交

Letcode -链表问题-刷题_第16张图片

思路:通过比较两个链表,得到两个链表的长度,让那个长的链表先走两个链表相差的步数(如果相交后面的数据地址都会相等),再让两个链表同时走,当两个链表的地址相同时,即就是相交的节点,返回相交的交点.

Letcode -链表问题-刷题_第17张图片

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)

{

    if(headA==NULL||headB==NULL)

    {

        return NULL;

    }

    struct ListNode *list1=headA;

    struct ListNode *list2=headB;

    int lenA=0,lenB=0;

    while(list1)//list1的长度

    {

        list1=list1->next;

        lenA++;

    }

    while(list2)//list2的长度

    {

        list2=list2->next;

        lenB++;

    }

    if(list1!=list2) /如果最后不相等

    {

        return NULL;

    }

     struct ListNode *shortlist=headA;

     struct ListNode *longlist=headB;

    if(lenA>lenB)//链表长度比较

    {

        shortlist=headB;

        longlist=headA;

    }

    int gap=abs(lenA-lenB);

    while(gap--)

    {

        longlist=longlist->next;

    }

    while(shortlist!=longlist)//找相同节点

        {

          shortlist=shortlist->next;

          longlist=longlist->next;  

        }

    return longlist;

}

OJ-141给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false

Letcode -链表问题-刷题_第18张图片

思路:使用快慢指针,若当慢指针等于快指针时,即有环,此时若有环的话,fast已经走完n圈,slow才与它相遇 

Letcode -链表问题-刷题_第19张图片

bool hasCycle(struct ListNode *head)

{

    if(head==NULL)

    {

        return false;

    }

    struct ListNode *slow=head;

    struct ListNode *fast=head;

    while(fast&&fast->next)

    {

        fast=fast->next->next;

        slow=slow->next;

        if(fast==slow)

        {

            return true;

        }

    }

    return false;

}

OJ-175-面试题:

Letcode -链表问题-刷题_第20张图片

Letcode -链表问题-刷题_第21张图片

Letcode -链表问题-刷题_第22张图片Letcode -链表问题-刷题_第23张图片

Letcode -链表问题-刷题_第24张图片

OJ-142-环形链表 II

       给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况不允许修改链表。

思路:按照OJ-175上面推出来的公式进行写就ok

struct ListNode *detectCycle(struct ListNode *head)

{

     struct ListNode *slow=head;

    struct ListNode *fast=head;

     if(fast==NULL||fast->next==NULL)

     {

         return NULL;

     }

    while(fast&&fast->next)

    {

        slow=slow->next;

        fast=fast->next->next;

        if(fast==slow)

        {

           struct ListNode *meet=fast;

            while(meet!=head)

            {

                head=head->next;

                meet=meet->next;

            }

            return meet;

        }

    }

   return NULL;

}

OJ-138-复制带随机指针的链表

   给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。

思路:1.拷贝节点链接在原节点后面

Letcode -链表问题-刷题_第25张图片

     2.处理拷贝节点的random

Letcode -链表问题-刷题_第26张图片

Letcode -链表问题-刷题_第27张图片

struct Node* copyRandomList(struct Node* head)

{

    if(head==NULL)

    {

        return NULL;

    }

      struct Node*cur=head;

    while(cur)

    {

        struct Node*next=cur->next;

        struct Node*copy=(struct Node*)malloc(sizeof(struct Node));

        copy->val=cur->val;

        copy->next=next;

        cur->next=copy;

        cur=next;

    }

    //处理random

    cur=head;

    while(cur)

    {

        struct Node*copy=cur->next;

       if(cur->random==NULL)

       {

           copy->random=NULL;

       }

        else

        {

            copy->random=cur->random->next;

        }

        cur=copy->next;

    }

    //把链表拿出来

    cur=head;

    struct Node*copyhead,*copytail;

    copyhead=copytail=(struct Node*)malloc(sizeof(struct Node));

    while(cur)

    {

        struct Node*copy=cur->next;

        struct Node*next=copy->next;

        copytail->next=copy;

        copytail=copytail->next;

        cur->next=next;

        cur=next;

    }

  struct Node*guard=copyhead;

    copyhead=copyhead->next;

    free(guard);

    return copyhead;

}

Oj- 147-对链表进行插入排序

Letcode -链表问题-刷题_第28张图片

Letcode -链表问题-刷题_第29张图片

思路:通过创建一个新链表,取原链表的第一个节点作为新链表的头节点,然后从原链表中拿出新节点遍历对比,比谁小的数据就在这个数据前进行插入,

Letcode -链表问题-刷题_第30张图片

Letcode -链表问题-刷题_第31张图片

Letcode -链表问题-刷题_第32张图片

Letcode -链表问题-刷题_第33张图片

struct ListNode* insertionSortList(struct ListNode* head)

{

    if(head==NULL||head->next==NULL)

        return head;

    struct ListNode*sorthead=head;

     struct ListNode*cur=head->next;

    sorthead->next=NULL;

    while(cur)//开始条件

    {

        struct ListNode*next=cur->next;

         struct ListNode*p=NULL;

         struct ListNode*c=sorthead;

        while(c)

        {

            if(cur->valval)//有小于的数据在在循环外处理

            {

              break;

              

            }

            else

            {

                p=c;

                c=c->next;

            }

        }

              if(p==NULL)

                    {

                       cur->next= c;

                        sorthead=cur;

                    }

                    else

                    {

                    p->next=cur;

                    cur->next=c;

                    }

        cur=next;



        }

    return sorthead;

}

JZ76-删除链表中重复的结点

Letcode -链表问题-刷题_第34张图片

思路:用三指针方法解决,

Letcode -链表问题-刷题_第35张图片

特殊情况

Letcode -链表问题-刷题_第36张图片

struct ListNode* deleteDuplication(struct ListNode* pHead )

{

    struct ListNode*fast=pHead->next;

    struct ListNode*slow=pHead;

    struct ListNode* prev=NULL;

   if(pHead==NULL)

   {

       return NULL;

   }

    else

    {

        while(fast)

        {

            if(fast->val!=slow->val)

            {

                prev=slow;

                fast=fast->next;

                slow=slow->next;

            }

            else

            {

                while((fast!=NULL)&&(slow->val==fast->val))

                {

                    fast=fast->next;

                    if(prev==NULL)

                    {

                        pHead=fast;

                    }

                    else

                    {

                        prev->next=fast;

                    }

                }

                while(slow!=fast)

                {

                    struct ListNode*p=slow;

                    slow=slow->next;

                    free(p);

                }

                if(fast!=NULL)

                {

                    fast=fast->next;

                }

            }

        }

    }

       return pHead;

}

兄弟们-看到这里了,不关注一波

 

你可能感兴趣的:(数据结构,链表,数据结构,c语言,leetcode,后端)