每日一题(复制带随机指针的链表)

简介: 每日一题(复制带随机指针的链表)

每日一题(复制带随机指针的链表)


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


a3ae6dd7a9e122ba676f866deb69e53e_8ed4e12d881946368f593a4a8ce71fbe.png


思路:


由于每个链表还包含了一个random节点指向了链表中的随机节点,所以并不能直接照搬复制原链表。首先想到的暴力思路是复制一条新的链表。找到原链表的每个节点的random到该节点的相对举例。但是实际上操作起来更复杂。


这里提供另外一个思路:


  • 第一步:创建新节点

在原链表的每个节点之后紧跟着复制一个节点,形成新老节点相间的局面,并且将原链表的每个节点的值赋值给其后创建的节点中,并且将新开辟的节点的random成员的值设置为NULL,如下图:

deff64c4ca939517870d90b93b2069ad_5ef6fdb80e8a44eea7b3f9afc3a844a6.png



  • 第二步:设置新节点random的值

创建一个cur指针指向原链表的第一个节点,再创建一个newhead指针指向cur的next;cur指针从head处出发,newhead从head->next处出发。开始遍历链表。这里有一个最重要的关系:当cur->random不为空时,(当cur->random的值为NULL时,则不做改动)满足:cur->random与cur的对应关系与newhead->random和cur->random->next的对应关系时一样的。


就可以根据这些对应关系修改新创建的节点的random的值。接着cur向后移动两步指向下一个原链表中的节点,newhead也向后走两步指向下一个新开辟的节点。如下图所示(红色的是random指针,绿色的是next指针):新节点之间的random的链接关系和原链表的random的链接关系并没有改变。

7cdce1a36a313de12c02df94607ba4d9_28d64aa891ce4b87aa21a64154f31021.png


  • 第三步:断开链表

创建三个指针cur1和cur2和newhead,cur1从head的next处开始遍历,cur2从head处开始遍历,newhead指针用于记录cur1的起始位置。将原链表的节点和新链表的节点各自分成一条链表。特别注意:这里的遍历迭代的顺序不得交换! 在两个指针向后更新的过程中,肯定是cur1->next先为NULL,当cur1->next为NULL时就退出循环,但是此时的cur2的next指针仍然指向的是新开辟的最后一个节点。所以在返回newhead之前,要将cur2->next置为NULL。

1decc96244f11bbd3e7710005901f303_7af95de5e06b4b84a4ca66f23cc5bdbe.png


代码实现:


  if(head==NULL)
    {
        return NULL;
    }
    struct Node* cur = head;
    struct Node* curNext = head;
    struct Node* newhead = head;
    //构造相间的节点
    while(cur!=NULL)
    {
        curNext = cur->next;
        struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
        if(newnode== NULL)
         return NULL;
        newnode->val = cur->val;
        newnode->random =NULL;
        //新节点链接在原节点之后
        cur->next = newnode;
        newnode->next = curNext;
        cur = curNext;
    }
    cur = head;
    //复制各自的random
    while(cur!=NULL)
    {
        newhead = cur->next;
        if(cur->random!=NULL)
        {
            newhead->random = cur->random->next;
        }
        cur = cur->next->next;
    }
    //断开
    newhead = head->next;
    struct Node* cur1 = newhead;//cur1用于遍历newnode
    struct Node* cur2 = head;//cur2用于遍历原链表的节点
    while(cur1->next)
    {
        cur2->next = cur2->next->next;
        cur1->next = cur1->next->next;
        cur2 = cur2->next;       
        cur1 = cur1->next;
    }
  //将cur2->next置空
    cur2->next = NULL;
    return newhead;


完结


复制带随机指针的链表习题的分析就到这里啦,若有不足,欢迎评论区指正,下期见!


目录
打赏
0
0
0
0
1
分享
相关文章
用指针处理链表
用指针处理链表
131 3
|
9月前
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
66 1
链表指针的传参,传值和传地址
|
9月前
|
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
62 0
|
9月前
|
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
103 0
|
12月前
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
108 1
【数据结构OJ题】复制带随机指针的链表
|
11月前
|
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
62 1
链表—初始化指针变和创建新的节点------区别应用分析
链表—初始化指针变和创建新的节点------区别应用分析
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问