深拷贝一个链表很简单,遍历链表,得到其中的数据,再根据这个数据创建节点,每创建一个节点就将其串联起来。但本题中节点与节点有两种关系,单链表只有一种向下传递的关系,这里多了一个随机指针。
那么在遍历原始链表时就不能同时拷贝其随机指针,因为随机指针指向随机,很可能指向还未遍历到的节点,那么新链表中对应的节点也就没被创建好,无从指向。由此得知,随机指针必须有所指,那么必须在所有新的节点创建完成之后,才能将随机指针指过去。再者提到了一个对应节点,每对新旧节点之间需要有一个对应关系,否则无从知道原始节点上的随机指针指向的节点对应于新节点上的哪个节点。
根据上述思路,先将节点按照正常的深拷贝链表拷贝过去,满足了第一条要求的随机指针要有所指向。再在复制节点时保留其对应关系,满足了第二条的对应要求。最后遍历一遍原始链表,得到原始链表节点上的随机指针对应的新链表上的节点。
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if (head == nullptr) return nullptr;
RandomListNode *result = new RandomListNode(head->label);
RandomListNode *masterNext = head->next, *slaveNext = result;
ump[head] = result;
while (masterNext != nullptr) {
RandomListNode *q = new RandomListNode(masterNext->label);
slaveNext->next = q;
ump[masterNext] = q;
slaveNext = slaveNext->next;
masterNext = masterNext->next;
}
slaveNext->next = nullptr;
masterNext = head, slaveNext = result;
while (masterNext != nullptr) {
slaveNext->random = ump[masterNext->random];
masterNext = masterNext->next;
slaveNext = slaveNext->next;
}
return result;
}
private:
unordered_map<RandomListNode *, RandomListNode *> ump;
};