题目描述:
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点
要求返回这个链表的深拷贝
示例:
输入:
{"$id":"1","next":
{"$id":"2","next":null,"random":
{"$ref":"2"},"val":2},"random":
{"$ref":"2"},"val":1}
解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node() {}
Node(int _val, Node* _next, Node* _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
思路分析:
<1>在原有链表每个节点后面插入一个值相同的新节点
<2>对插入的新节点的随机指针域赋值
<3>将插入的新节点从原链表中拆出来
注意:
1.循环中语句的顺序
2.插入新节点的循环跳出条件是p1->next!=NULL,需要出循环之后单独处理
3.跳出条件如果为p1!=NULL,会发生段错误
4.给随机指针域赋值时,p1->random可能为空,需要分情况处理
代码实现:
class Solution {
public:
Node* BuyNode(int val)
{
Node* newnode=(Node*)malloc(sizeof(Node));
if(newnode==NULL)
{
assert(0);
}
newnode->val=val;
newnode->next=NULL;
newnode->random=NULL;
return newnode;
}
Node* copyRandomList(Node* head)
{
if(head==NULL)
{
return NULL;
}
//原链表中每个节点后都插入一个值相同的节点
Node* p1=head;
while(p1->next!=NULL)
{
Node* node=BuyNode(p1->val);
node->next=p1->next;
p1->next=node;
p1=node->next;
node=p1->next;
}
Node* node=BuyNode(p1->val);
p1->next=node;
node->next=NULL;
//给新插入的节点的随机指针域赋值
p1=head;
Node* p2=head->next;
Node* phead=p2;
while(p1!=NULL)
{
if(p1->random!=NULL )
{
p2=p1->next;
p2->random=p1->random->next;
p1=p2->next;
}
else
{
p2=p1->next;
p2->random=NULL;
p1=p2->next;
}
}
//将新插入的节点从原链表中拆出来
p1=head;
p2=head->next;
while(p1->next!=NULL)
{
p1->next=p2->next;
p1=p2;
p2=p1->next;
}
return phead;
}
};