请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个
random 指针指向链表中的任意节点或者 null。示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]] 示例 2:输入:head = [[1,1],[2,1]] 输出:[[1,1],[2,1]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
1.利用哈希表存储。哈希表的key是每个node的指针,value是利用node的val新建的节点,然后通过遍历key 将每个value链接在一起
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr)return head;
unordered_map<Node*,Node*>NodeMap;
Node* tmp=head;
while(tmp!=nullptr)
{
NodeMap[tmp]=new Node(tmp->val);//每个value都是一个新结点
tmp=tmp->next;
}
tmp=head;
while(tmp!=nullptr)
{
if(tmp->next)//如果原链表存在next
{
NodeMap[tmp]->next=NodeMap[tmp->next];//将对应新节点指向新节点
}
if(tmp->random)//如果原链表存在random
{
NodeMap[tmp]->random=NodeMap[tmp->random];//将对应新节点指向新节点}
tmp=tmp->next;
}
return NodeMap[head];
}
};
2.原地方法,
(1)将原链表扩展成双倍,如1-2-3 变为 1-1-2-2-3-3.每个节点后面创建一个新节点
(2)将旧节点的random赋值给新节点的random
(3)将新旧节点分成两个节点
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL)return head;
Node* cur=head;
while(cur)//扩展链表
{
Node* temp=new Node(cur->val);
temp->next=cur->next;
cur->next=temp;
cur=cur->next->next;
}
cur=head;
while(cur)//将random指针复制给新节点
{
if(cur->random)
{
cur->next->random=cur->random->next;
}
cur=cur->next->next;
}
Node* dummy=new Node(0);
cur=head;
Node* res=dummy;
while(cur)//分离新旧链表
{
res->next=cur->next;
cur->next=cur->next->next;
cur=cur->next;
res=res->next;
}
return dummy->next;
}
};