138. 复制带随机指针的链表
思路:
这题的意思比较模糊,为什么不能直接复制呢?
浅复制,关系和地址都一样;深复制,关系一样,但地址不一样。
同时因为有一个random指针,它的指向是随机的,因此如果遍历复制就会导致一个问题,如果前面的节点的random指向后面的节点,但后面的节点还没有被创建,此时random就会指向null,那么结果就不同了。所以我们需要先创建复制节点,同时保留复制节点和原节点的映射关系。什么是映射关系呢?在这里理解就是 寻找到原节点后能通过某种关系得到复制节点的信息。如果我们需要有映射关系可以考虑哈希表,映射关系为 键-值 一一映射。同时哈希表的O(1)的查找效率便于操作。
那么需要做的就是,先把所有节点的val和next复制,在遍历一遍通过映射关系填充random指针指向。那么时间和空间复杂度都为O(n)
代码:
/*
// 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 NULL;
unordered_map<Node*,Node*> ref;
Node* copynode = new Node(-1);
for(auto p = head;p;p=p->next ){
Node* node = new Node(p->val);
copynode->next = node;
copynode = copynode->next;
ref[p] = node;
}
for(auto p = head;p;p=p->next){
ref[p]->random = ref[p->random];
}
return ref[head];
}
};