原题链接:
https://leetcode-cn.com/problems/copy-list-with-random-pointer/
https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
1、map+递归
map<Node*,Node*> map;
Node* copyRandomList(Node* head) {
if(head==NULL){
return NULL;
}
if(map.count(head)){//如果已经复制了该节点,则直接返回即可
return map[head];
}
Node* node=new Node(head->val);//复制该节点
map[head]=node;//将该节点对应的新建节点存入map,再次遍历到该节点时,则直接返回
node->next=copyRandomList(head->next);//递归复制该节点的next指针和random指针
node->random=copyRandomList(head->random);
return node;
}
2、map+迭代
map<Node*,Node*> map;
Node* getClonedNode(Node* node){
if(node!=NULL){
if(map.count(node)){
return map[node];
}else{
Node *tmp=new Node(node->val);
map[node]=tmp;
return tmp;
}
}
return NULL;
}
Node* copyRandomList(Node* head) {
if(head==NULL){
return NULL;
}
Node* oldNode=head;
Node* newNode=new Node(oldNode->val);//创建新节点
map[oldNode]=newNode;
while(oldNode!=NULL){//在旧链表上迭代,复制所有节点
newNode->random=getClonedNode(oldNode->random);//获取random指针引用的节点的克隆
newNode->next=getClonedNode(oldNode->next);//获取next指针引用的节点的克隆
oldNode=oldNode->next;
newNode=newNode->next;
}
return map[head];
}
3、交错链表
第一步(来源):复制原始节点,生成交错链表
第二步:链接复制节点
第三步:分解交错链表,返回复制节点链表
Node* copyRandomList(Node* head) {
if(head==NULL){
return NULL;
}
//创建原始节点和复制节点交错的链表
Node* p=head;
Node* newNode=NULL;
while(p!=NULL){
newNode=new Node(p->val);
newNode->next=p->next;
p->next=newNode;
p=newNode->next;
}
p=head;
while(p!=NULL){//依据原始节点对复制节点的random进行链接
p->next->random=(p->random!=NULL)?p->random->next:NULL;
p=p->next->next;
}
//将链表分解,以获得原始节点链表和复制节点链表
p=head;
newNode=p->next;
while(p!=NULL&&p->next!=NULL){
Node *tmp=p->next;
p->next=tmp->next;
p=p->next;
tmp->next=(p!=NULL)?p->next:NULL;
}
return newNode;
}