leetcode一道比较难的链表题

本文详细解释了如何复制一个随机链表,分为三个步骤:1)拷贝节点值并链接;2)处理random指针;3)尾插法连接新链表。展示了关键代码片段以帮助理解。
摘要由CSDN通过智能技术生成

在这里插入图片描述
今天还是继续来分享我们的链表题,这个题目有点难,主要是思路比较难想,但是如果沥青思路写起来就比较简单了(我乱讲的)

随机链表的复制

在这里插入图片描述

这个是题目的描述,大家也可以在链接里看,那我把这道题目分成三个解题步骤,第一个步骤是我们拷贝一个一摸一样的结点在没个节点后面,但是一模一样的节点我们要把它的值拷贝过来很简单,但是如是是它的random呢,我们只知道图中的节点指向哪里,但是我们不知道它的random到底该怎么解决,那我们得先malloc一个节点,然后插入到上面节点的每一个后面,并把他们继续链接起来,然后进行值拷贝,就是拷贝val这个值,步骤一我们只要完成val的赋值在加上在没一个节点的后面进行链接就行了,我们这里的思路是写一个循环用cur表示当前的位置,copy就是我们需要在cur节点后面进行链接的节点,下面给大家一个图,让大家更好的理解我们的意思和代码。

在这里插入图片描述
那我们就需要在每个节点后面链接,我们这里相当于单链表的随即插入要进行的步骤,首先我们得要一个next的指针来保存后面的节点,这样才能进行链接要不然cur进行下一个步骤的时候就会存在链接不上。步骤一的代码

struct Node* cur = head;
   
    while(cur)
    {
        struct Node* next = cur->next;
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        cur->next = copy;
        copy->next = next;
        cur = next;
    }

这样就能保证我们上面的这个图也是可以成立的,其实这道题的暴力求解也可以解决,但是会存在问题,时间复杂度是O(N的平方),我们的步骤二就是该解决我们random,大家有没有想过我们步骤一的作用就那么简单,其实不是的,因为我们的下一步就是需要怎么样把random放到我们malloc的节点,我们的的cur节点的random是不是可以准确找到,那我们copy的random是不是就是该cur节点的random的next这个节点就是我们当前copy这个节点,步骤一不仅仅把val进行值拷贝,还起到我们链接的作用,代码就是

 cur = head;
    struct Node* copy = cur->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;

        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = cur->next->next;
        if(cur)
            copy = cur->next;
    }

下一步取出这些节点,在进行链接就行,我们可以用单链表的尾插思路进行实现,我因为之前文章写过尾插的思路,这里就直接给出代码。


    cur = head;
    
    struct Node* newhead = NULL;
    struct Node* tail = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
         struct Node* next = copy->next;
        if(newhead == NULL)
        {
            newhead = copy;
            tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }
        cur->next = next;
        cur = next;

    }
    tail->next = NULL;

那我们运行编译之后还有就是如果我们的链表是空的情况就直接返回空指针就可以了,下面就是我们这道题的完整代码。

struct Node* copyRandomList(struct Node* head) {
	struct Node* cur = head;
    if(head == NULL)
        return NULL;
    while(cur)
    {
        struct Node* next = cur->next;
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        cur->next = copy;
        copy->next = next;
        cur = next;
    }
    cur = head;
    struct Node* copy = cur->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;

        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = cur->next->next;
        if(cur)
            copy = cur->next;
    }

    cur = head;
    
    struct Node* newhead = NULL;
    struct Node* tail = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
         struct Node* next = copy->next;
        if(newhead == NULL)
        {
            newhead = copy;
            tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }
        cur->next = next;
        cur = next;

    }
    tail->next = NULL;
   
    return newhead;
       

}

那今天的分享就到这里,我们下次再见。
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在冬天去看海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值