目录
前言
小伙伴们大家好啊!今天为大家带来一篇力扣上不常见的链表题目:复制带随机指针的链表。
一,题目分析
那么我们废话不多说,首先来看一下题目要求。
如上图所示,当前题目要求,我们需要将一个带有随机指针的链表进行 “深度拷贝”。既然是深度拷贝,当然就是将该链表中的基本所有的内容都需要拷贝过来。
比如题目中要求的,对于链表的每个节点的内容,每个节点的一个 next 指针和一个随机指针,都需要进行拷贝,但是同时需要注意的是,新链表的每个节点的 next 指针和 random 指针都不可以指向原链表,而是指向新链表中原链表的那个关系。
二,思路分析
那么通过我们对于题目的分析,我们有以下思路实现,当然不仅仅只有一种实现方法,只是我们在这里就通过这种方式去实现。
步骤一:
如上图所示。首先,我们考虑到的是,将每个节点拷贝一份,然后将其分别链接到原链表的两个节点之间。
然后对于代码实现来说,就是将新节点的 val 和 next 值拷贝之后,再将其链接到原链表中,然后让原链表的指针一直往下走。代码实现:
步骤二:
通过第一步之后,我们已经将原链表节点的 val 值和 next 指针复制好了。接下来我们需要将每个节点的 random 指针复制。
我们发现,当我们完成步骤一之后,一部分新插入的节点的 random 指针都是自己的 next 指针的 random 指向的内容,也就是每个 copy->random=cur->next->random;而另一部分则是指向空的节点,只需要将其赋为空即可。
于是我们就得到了下面所示的图:
那么对于代码实现,我们需要注意的就是原链表的指针的移动,因为已经链接上了插入节点,所以不能直接移动,得通过插入节点的指针移动。
步骤三:
经过以上步骤之后,我们其实已经完成了拷贝,但是我们需要将新链表从原链表上脱离,再将其链接起来形成一个新链表。然后就得到了我们最后的链表。
那么通过上面的图,首先,我们需要一个没有头节点的新链表。然后进行单链表的头插。
在进行头插的时候,我们有这样几个需要注意的点:
1.头节点为空时,需要直接链接。
2.头节点不为空,正常插入。cur 每次移动是根据 copy 的 next 。
3.coypTail 最为新链表的移动指针,也是需要移动的,只不过它只在自己链表上移动,不会涉及到 cur 。
代码实现:
那么最后,我们只需要将新链表的指针 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;
}
好的,那么对于带随机指针的链表的深度拷贝到此就结束啦!如果小伙伴们有问题,可以随时留言评论哦!
总结
写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 java开发 的学习思路及方向。从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的 点击我的Gitee获取。
还有 高级java全套视频教程 java进阶架构师 视频+资料+代码+面试题!
全方面的java进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。