给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
示例:
输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。
提示:
你必须返回给定头的拷贝作为对克隆列表的引用。
思路分析:利用map关联式容器辅助。第一遍扫描复制节点,并将原链表中的所有节点与新复制的节点一一对应的关联,再扫描一遍原链表复制next、random指针内容。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node() {}
Node(int _val, Node* _next, Node* _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
map<Node*, Node*> myMap;
Node *pHead = head, *tempPtr;
//扫描链表,复制所有的节点
while (pHead != NULL) {
tempPtr = new Node(pHead->val, pHead->next, pHead->random);
myMap[pHead] = tempPtr;//将原节点与新节点一一对应的关联
pHead = pHead->next;
}
myMap[NULL] = NULL;
pHead = head;
//再次扫描链表,复制next、random指针
while (pHead != NULL){
myMap[pHead]->next = myMap[pHead->next];
myMap[pHead]->random = myMap[pHead->random];
pHead = pHead->next;
}
return myMap[head];
}
};
方法二:
① 首先扫描链表,复制所有的节点,并将复制的节点插入到原先节点的后面。
②再次扫描节点,复制所有原节点random指针域、
③再将两个链表拆开
算法示意图
初始状态
执行第一步复制节点
执行第二步复制random指针域
执行第三步拆分链表。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node() {}
Node(int _val, Node* _next, Node* _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == NULL){
return NULL;
}
Node *pHead = head, *tempPtr;
//扫描链表,复制所有的节点
while (pHead != NULL) {
tempPtr = new Node(pHead->val, pHead->next, pHead->random);//复制节点
//将这个复制的节点插入到复制源的后面
tempPtr->next = pHead->next;
pHead->next = tempPtr;
pHead = pHead->next->next;//移动必须是移动两个一次,因为刚刚在后面插入了一个复制的节点
}
//再次扫描节点,复制random节点
pHead = head;
while (pHead != NULL) {
if (pHead->random != NULL) {
//pHead->next是pHead的复制,所以pHead->random->next的复制是pHead->random
pHead->next->random = pHead->random->next;
}
else {
pHead->next->random = NULL;
}
pHead = pHead->next->next;
}
//在将两个链表拆开
pHead = head;
Node *copyHead = pHead->next;
while (pHead != NULL) {
tempPtr = pHead->next;
pHead->next = pHead->next->next;
if (tempPtr->next != NULL) {
tempPtr->next = tempPtr->next->next;
}
pHead = pHead->next;
}
return copyHead;
}
};