138. 复制带随机指针的链表
创始人
2024-04-05 19:46:35

LeetCode题解

  • 前言
  • 复制带随机指针的链表

前言

在刷题的过程中,遇到了一个很棒的思路,与是便记录了下来!!!
😊😊😊

复制带随机指针的链表

题目描述:
在这里插入图片描述
➡️挑战链接⬅️
分析:

题目描述的很长,但是仔细阅读的话,我们会发现题目想表达的意思很明确;
就是将题目给的链表,完整的复制一份,包括复制各节点之间的链接关系;
首先链接关系中,next指针域的节点指针很好复制,现在问题是怎么复制random指针域的关系?
第一种思路:
我们可以相对位置的关系,来找到拷贝链表的random;
什么个意思嘞?
在这里插入图片描述

就比如,声明: 下面的链表是对原链表的拷贝(此时还没有处理random指针域),copy表示是对饮原链表节点cur的拷贝
既然copy是cur的拷贝,那么cur在原链表的相对位置,与copy节点在拷贝链表的相对位置应该是一样的,对吧!就比如图中cur相对于原链表来说在距离原链表偏移量为2的位置,同理对应的copy节点也应该在拷贝链表偏移量为2的地方;
好,有了以上的认识,我们处理起拷贝节点的指针就比较容易了;
按照刚才的道理,那么我cur->random是不是也有个相对位置,那我copy->random的相对位置是不是应该和cur->random的相对位置一样?
该是这样吧,就比如图中cur->random在相对于链表位置为4的位置,那么我的copy->random也应该在相对与链表位置为4的地方,也就是下图所表示的地方:
在这里插入图片描述
你看这样我们是不是就找到copy节点的random指针了;是不是就完成了对于random指针的一份拷贝;
上面的过程总结一下就是:
1、先形成一份拷贝链表(还没有复制随机指针的关系)
2、根据copy节点,求出原节点(cur节点)的随机指针相对链表的相对位置,然后我们根据该相对位置,去拷贝链表里面寻找随机指针;最后我们一定会找到copy节点应该链接的随即指针,链接起来就好了;

时间复杂度:O(N^2)
空间复杂度:O(1)

代码实现:

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/////搜索原节点的random指针相对于原链表的相对位置
int SearchStep(struct Node*head,struct Node*random)
{if(random==NULL)//如果原节点的随机指针是NULL,直接返回-1,就好了return -1;struct Node*cur=head;int step=0;while(cur){if(cur==random)break;else{step++;cur=cur->next;}}return step;
}
//根据相对位置去拷贝链表里面寻找copy节点的随机指针
struct Node*CopyRandom(struct Node*head,int step){struct Node*cur=head;while(step--)cur=cur->next;return cur;}
struct Node* copyRandomList(struct Node* head) {struct Node*CopyHead=NULL;//存储拷贝链表的头struct Node*cur=head;struct Node*copy=NULL;struct Node*tail=NULL;while(cur)//形成拷贝链表{copy=(struct Node*)malloc(sizeof(struct Node));copy->val=cur->val;if(CopyHead==NULL){CopyHead=tail=copy;tail->next=NULL;}else{tail->next=copy;tail=copy;tail->next=NULL;}cur=cur->next;}cur=head;copy=CopyHead;while(cur){struct Node*random=cur->random;int step=SearchStep(head,random);//定位cur节点的随机指针在链表中的相对位置if(step==-1){copy->random=NULL;}else{//根据相对位置去定位copy节点的随机指针struct Node*copyrandom=CopyRandom(CopyHead,step);copy->random=copyrandom;}               cur=cur->next;copy=copy->next;}return CopyHead;
}

在这里插入图片描述

第二种方法:
这个方法,真的棒的出奇!!我很佩服那些能想出这种逆天的方法的,该方法直接将时间复杂度缩小到O(N);
思路:
我们现在夫吧拷贝节点链接起来,我们现在将它们放在对应原节点的后面,并把它们链接起来,说白了就是将拷贝节点链接在原节点的屁股后面!!😊😊😊画图就是这样:
在这里插入图片描述
链接完毕过后,我们就该处理拷贝节点的随机指针问题了;
以上面为例
我们copy是cur的一份拷贝嘛,那么现在我cur的random是null,那我copy是不是也应该模仿者cur让我的random也指向跟cur的random的一份一摸一样的节点(不能是同一个节点)cur的random指向NULL,那我copy->random也应该指向空;好了现在我更新我的cur和copy:
在这里插入图片描述
我copy是cur的一份拷贝,我cur所做的一切动作,我copy都会跟着一起模仿,现在我cur的random指向7,那么好了我copy->random是不是也应该指向一份7(copy不能和cur指向同一个7),那么我是不是就应该指向cur节点的random的一份拷贝啊!那这份拷贝在哪里呢?
是不是就在cur节点的random节点的后面啊,我们刚开始就将原链表的每个节点的拷贝节点链接在了后面,于是我们 copy->random=cur->random->next; 这样就解释了我们刚才第一步为什么要把拷贝节点全部连接在原节点的后面;这样一来我们不就解决了copy节点的random指针的复制问题了嘛;
如果上面的描述还没让你明白,我们在举个通俗一点的例子:
假设cur和copy是双胞胎,cur是大哥,copy是小弟;
random就相当于女朋友;
现在大哥的女朋友很能干,很贤惠啊!小弟呢也想找个这样的女朋友,于是他就叫他大哥给他介绍个,大哥呢,就想到了女朋友的妹妹是跟女朋友一摸一样的人,于是嘞,他就将女朋友的妹妹介绍给了弟弟;而这个女朋友的妹妹在哪里嘞?是不是通过女朋友就能找到?(就在女朋友的后面);
于是弟弟就通过哥哥女朋友的介绍链接到了妹妹的存在;
但是现在我拷贝节点的指针指向问题虽然是解决了,但是我的原节点和拷贝节点链接在了一起,我们得想办法恢复原链表的链接关系和剪下拷贝节点嘛,这样我们才能满足题意;

综上所述:
1、将拷贝节点链接在对应原节点的后面;
2、解决掉拷贝节点的随机指针指向问题;
3、恢复原链表和剪下拷贝节点并形成拷贝链表;

思路虽然有了,但是代码写起来还是得画图才行,我么先来解决第一条:
在这里插入图片描述
在这里插入图片描述
第二步复制随机链表:
在这里插入图片描述
在这里插入图片描述

第三步恢复原链表和剪下拷贝节点并形成拷贝链表
在这里插入图片描述
在这里插入图片描述
代码实现:

struct Node* copyRandomList(struct Node* head) {struct Node*cur=head;struct Node*next=NULL;struct Node*NewNode=NULL;//1、开始链接链表while(cur){next=cur->next;NewNode=(struct Node*)malloc(sizeof(struct Node));NewNode->val=cur->val;cur->next=NewNode;NewNode->next=next;cur=next;}//2、开始复制随机指针cur=head;struct Node*copy=NULL;while(cur){copy=cur->next;if(cur->random==NULL){copy->random=NULL;}else{copy->random=cur->random->next;}cur=copy->next;}//3、开始剪切链表和复原链表cur=head;struct Node*plist=NULL;//存储拷贝链表头节点struct Node*tail=NULL;while(cur){copy=cur->next;next=copy->next;//开始剪切拷贝链表if(tail==NULL)plist=tail=copy;else{tail->next=copy;tail=copy;tail->next=NULL;}cur->next=next;//复原原链表cur=next;}return plist;
}

时间复杂度:O(N)
空间复杂度:O(1)

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...