题意理解:实现带指针结构体的深拷贝。深拷贝和浅拷贝的区别主要在于拷贝一个带引用或者指针的结构体时,深拷贝会开辟一块新内存,然后让克隆体的指针或引用指向这块内存;浅拷贝则不会开辟新内存,而是让克隆体的指针或引用直接指向原内存。
回到这到题目就是,拷贝一个节点时,不能仅仅把人家的val拷贝进去,random指针的指向、next指针的指向也要考虑,否则就可能出现我明明克隆体的random指针指向节点的val都对了,为什么还是报Random pointer of node with val 13 points to a node not in the copied list的错误这一问题
可以用一个存储<node*,node*>的hash表先复制原链表,然后再构造新的链表,具体构造方法见代码:
/*
// 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 nullptr;
unordered_map<Node*,Node*> mp;
Node* cur=head;
while(cur!=nullptr){
Node *n=new Node(cur->val);
mp[cur]=n;
cur=cur->next;
}
cur=head;
while(cur!=nullptr){
mp[cur]->next=mp[cur->next];
mp[cur]->random=mp[cur->random];
cur=cur->next;
}
return mp[head];
}
};
之前我写过一种错误的写法:
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr)
return nullptr;
Node *p,*q;
p=q=head;
Node *newhead=new Node(0);
p=newhead;
Node *cur=head;
while(cur!=nullptr){
Node *node=new Node(cur->val);
if(cur->random==nullptr)
node->random=nullptr;
else{
Node *node_r=new Node(cur->random->val);
node->random=node_r;
}
p->next=node;
p=node;
cur=cur->next;
}
return newhead->next;
}
};
问题就出在下面这段代码里,每一次我的node->random指向的都是一个新的节点,而这个节点除了val符合外,它的random、next都是空指针
相当于画了一个这样的链表:
即random指针指向的并不是链表里的节点