一、题目描述:138. 复制带随机指针的链表(中等)
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
示例:
输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。
提示:
你必须返回给定头的拷贝作为对克隆列表的引用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
创建节点copy,进入递归,将head的元素拷贝到copy,并且将copy保存在map<Node*,Node *> save里面,如果当前head的next节点不为空,当head->next节点的拷贝已经在save里面,则copy的节点的next指向save里面对应next节点,否则新创建node节点,进入递归复制head->next,copy->next;同理如果当前head的random节点不为空,则当head->random已经在save里面则copy->random 指向save里保存的random节点,否则新生成节点random,copy->random指向random,然后递归进入复制head->random,copy->random。
三、代码
/*
// 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;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
map<Node * ,Node *> save;
if(head == NULL)
return NULL;
Node * copy = new Node;
copy->next = NULL;
copy->random = NULL;
copyRandomList(head,copy,save);
//print(copy);
return copy;
}
void print(Node * node)
{
while(node != NULL)
{
cout<<node->val;
node = node->next;
}
}
void copyRandomList(Node* head,Node * copy,map<Node * ,Node *> & save)
{
if(save.count(head) > 0)
return;
copy->val = head->val;
save[head] = copy;
if(head->next != NULL)
{
if(save.count(head->next) > 0)
{
copy->next = save[head->next];
}
else
{
Node * next = new Node;
next->next = NULL;
next->random = NULL;
copy->next = next;
cout<<head->next->val<<",";
copyRandomList(head->next,next,save);
}
}
else
{
copy->next = NULL;
}
if(head->random != NULL)
{
if(save.count(head->random) > 0)
{
copy->random = save[head->random];
}
else
{
Node * random = new Node;
random->next = NULL;
random->random = NULL;
copy->random = random;
//cout<<head->random->val<<",";
copyRandomList(head->random,random,save);
}
}
else
{
copy->random = NULL;
}
}
};