LeetCode:138. 复制带随机指针的链表(含原码实现)

目录

前言

一,题目分析

二,思路分析

步骤一:

步骤二: 

步骤三:

三,原码实现


前言

小伙伴们大家好啊!今天为大家带来一篇力扣上不常见的链表题目:复制带随机指针的链表。

LeetCode:138. 复制带随机指针的链表(含原码实现)_第1张图片

一,题目分析

那么我们废话不多说,首先来看一下题目要求。

LeetCode:138. 复制带随机指针的链表(含原码实现)_第2张图片

如上图所示,当前题目要求,我们需要将一个带有随机指针的链表进行 “深度拷贝”。既然是深度拷贝,当然就是将该链表中的基本所有的内容都需要拷贝过来。

比如题目中要求的,对于链表的每个节点的内容,每个节点的一个 next 指针和一个随机指针,都需要进行拷贝,但是同时需要注意的是,新链表的每个节点的 next 指针和 random 指针都不可以指向原链表,而是指向新链表中原链表的那个关系。

二,思路分析

那么通过我们对于题目的分析,我们有以下思路实现,当然不仅仅只有一种实现方法,只是我们在这里就通过这种方式去实现。

步骤一:

LeetCode:138. 复制带随机指针的链表(含原码实现)_第3张图片

如上图所示。首先,我们考虑到的是,将每个节点拷贝一份,然后将其分别链接到原链表的两个节点之间。

然后对于代码实现来说,就是将新节点的 val 和 next 值拷贝之后,再将其链接到原链表中,然后让原链表的指针一直往下走。代码实现:

LeetCode:138. 复制带随机指针的链表(含原码实现)_第4张图片

步骤二: 

通过第一步之后,我们已经将原链表节点的 val 值和 next 指针复制好了。接下来我们需要将每个节点的 random 指针复制。

我们发现,当我们完成步骤一之后,一部分新插入的节点的 random 指针都是自己的 next 指针的 random 指向的内容,也就是每个 copy->random=cur->next->random;而另一部分则是指向空的节点,只需要将其赋为空即可。

于是我们就得到了下面所示的图:

LeetCode:138. 复制带随机指针的链表(含原码实现)_第5张图片

那么对于代码实现,我们需要注意的就是原链表的指针的移动,因为已经链接上了插入节点,所以不能直接移动,得通过插入节点的指针移动。

LeetCode:138. 复制带随机指针的链表(含原码实现)_第6张图片

步骤三:

经过以上步骤之后,我们其实已经完成了拷贝,但是我们需要将新链表从原链表上脱离,再将其链接起来形成一个新链表。然后就得到了我们最后的链表。

LeetCode:138. 复制带随机指针的链表(含原码实现)_第7张图片

那么通过上面的图,首先,我们需要一个没有头节点的新链表。然后进行单链表的头插。

在进行头插的时候,我们有这样几个需要注意的点:

1.头节点为空时,需要直接链接。

2.头节点不为空,正常插入。cur 每次移动是根据 copy 的 next 。

3.coypTail 为新链表的移动指针,也是需要移动的,只不过它只在自己链表上移动,不会涉及到 cur 。

代码实现:

LeetCode:138. 复制带随机指针的链表(含原码实现)_第8张图片

 那么最后,我们只需要将新链表的指针 copyHead 返回即可。

三,源码实现

struct Node* copyRandomList(struct Node* head) {
	//1,插入新节点S
    struct Node*cur=head;
    while(cur!=NULL)
    {
        struct Node*copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
        copy->next=cur->next;
        
        cur->next=copy;
        cur=copy->next;
    }
    //2,将原链表的关系赋值到新链表
    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=NULL;
    struct Node*copyTail=NULL;
    while(cur)
    {
        struct Node*copy=cur->next;
        if(copyTail==NULL)
        {
            copyHead=copyTail=copy;
        }
        else
        {
            copyTail->next=copy;
            copyTail=copy;
        }
        
        cur->next=copy->next;
        cur=copy->next;
    }
    return copyHead;
}

好的,那么对于带随机指针的链表的深度拷贝到此就结束啦!如果小伙伴们有问题,可以随时留言评论哦!

LeetCode:138. 复制带随机指针的链表(含原码实现)_第9张图片

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