【链表OJ 11】复制带随机指针的链表

简介: 【链表OJ 11】复制带随机指针的链表

前言:

💥🎈个人主页:Dream_Chaser~ 🎈💥

✨✨刷题专栏:http://t.csdn.cn/UlvTc

⛳⛳本篇内容:力扣上链表OJ题目


leetcode138. 复制带随机指针的链表


来源:138. 复制带随机指针的链表 - 力扣(LeetCode)


1. 问题描述


给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不

应指向原链表中的节点

例如,如果原链表中有 XY两个节点,其中X.random --> Y。那么在复制链表中对应的两个节点xy ,同样有x.random --> y

返回复制链表的头节点。

b5c3bad2039e4a79910b54fe3cdb73c5.png


题解接口:

struct Node* copyRandomList(struct Node* head) {
}


2.代码思路:


2.1拷贝节点插入到原节点的后面

       复制节点:遍历原链表,对于每个节点,创建一个副本节点,并将其插入到原节点的后面。

我们一步一步分解来做,首先malloc一个新的节点,然后让copy指针接收,让原链表第一个节点里面的val值赋值给新malloc出来的链表。

c43a92546f964cfcbbd5935070a6fcef.png

    最后记得将cur=next,让cur指向next,循环条件是cur不为NULL,再次回到循环,重复①②③④⑤⑥⑦的步骤

ee15dee0e3404dc7beb7877ca814ca5f.png

    这是链表的最后情况。

cd6a9028c1404698b2e92ecb825638ae.png


2.2控制拷贝节点的random    

  • 设置random指针:遍历链表,对于每个原节点,设置对应副本节点的random指针。
  1. 如果原节点的random指针为NULL,则副本节点的random指针也设置为NULL
  2. 否则,副本节点的random指针设置为原节点的random指针指向的节点的副本节点。

分解动作:

6208ceaf8fe4441f98a4784cceae6030.png

①把cur指针重新指向原链表头节点(head)


②进入while循环,条件是cur不为NULL,定义一个新指针copy然后让其指向新组成的链表头节点的下一个节点cur->next      


③     如果原链表的random域指向的地址为NULL,那么新节点的random域指向NULL,


        如果原链表的random域指向的地址不为NULL,那么此时将此时cur->random->next的地址赋值给新节点的copy->random


④将copy->next赋值给cur


循环①②③④步,结束条件是cur指向NULL


这是最终情况.

7e37d6c461244ec3a3cbcc66329ce484.png


2.3拷贝节点解下来尾插组成拷贝链表,恢复原链表

       分离链表:遍历合并后的链表,将链表分离为原链表副本链表。同时,恢复原链表的next指针,使其指向原链表的下一个节点;同时,构建副本链表,通过尾插法将副本节点依次添加到副本链表的末尾。

c84bb6d67c2f4284be3b20c79b2f6ff4.png

尾插:

e358240e59934a9385f13db1b4a02660.png

恢复链表

dedafd52ea884e78829e5d04c6d6a6a6.png

    循环条件依然是cur不为NULL,当cur指向NULL,循环结束直接返回副本链表的头节点copyHead


代码实现:

struct Node* copyRandomList(struct Node* head) {
    //1.拷贝节点插入在原节点的后面
    struct Node* cur=head;
    while(cur)
    {
    struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
    copy->val=cur->val;
    struct Node* next= cur->next;
    //插入
    cur->next=copy;
    copy->next=next;
    cur=next;
     }
    //2.控制拷贝节点的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;
    }
   // 3、拷贝节点解下来尾插组成拷贝链表,恢复原链表
    struct Node*copyHead =NULL,*copyTail=NULL;
    cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;
        //尾插
        if(copyTail == NULL)
        {
            copyHead= copyTail=copy;
        }
    else
    {
        copyTail->next=copy;
        copyTail=copyTail->next;
    }
    //恢复原链表
   cur->next=next;
    cur= next;
    }
    return copyHead;
}


执行:

14d05e5794124fb4b7b7ab0f0bb8ce03.png

   文章讲解到此结束,如有错误,欢迎指正 感谢支持!

相关文章
|
1月前
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
16 1
链表指针的传参,传值和传地址
|
1月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
1月前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
18 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
22 0
|
4月前
【数据结构OJ题】环形链表
力扣题目——环形链表
37 3
【数据结构OJ题】环形链表
|
4月前
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
51 1
【数据结构OJ题】复制带随机指针的链表
|
4月前
【数据结构OJ题】环形链表II
力扣题目——环形链表II
30 1
【数据结构OJ题】环形链表II
|
4月前
【数据结构OJ题】相交链表
力扣题目——相交链表
33 1
【数据结构OJ题】相交链表
|
3月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
20 1
|
3月前
|
存储 算法 数据处理
指针与链表
指针与链表
65 0