题目大意:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
意思就是:
给定一个链表,该链表的每一的node包含next和random两个指针.请对该链表进行复制.
解题思路:
设原始链表如下,细线表示next指针,粗线表示random指针,没有画出的指针均指向NULL:
算法1:我们在构建新链表的节点时,保存原始链表的next指针映射关系,并把指针做如下变化(蓝色为原始链表节点,紫红色为新链表节点):
然后在上图的基础上进行如下两步
1、构建新链表的random指针:比如new1->random = new1->random->random->next, new2->random = NULL, new3-random = NULL, new4->random = new4->random->random->next
2、恢复原始链表:根据最开始保存的原始链表next指针映射关系恢复原始链表
该算法时间空间复杂度均为O(N)
算法2:该算法更为巧妙,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:
同理分两步
1、构建新节点random指针:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next
2、恢复原始链表以及构建新链表:例如old1->next = old1->next->next, new1->next = new1->next->next
注意的两点是:
1,算法.
2,如何保存原来链表的对应关系,并在最后回复原来的链表.
struct RandomListNode{
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL){}
};
class Solution{
public:
RandomListNode* copyRandomList(RandomListNode* head){
if(!head){
return NULL;
}
map<RandomListNode*, RandomListNode*> storage;
storage[head] = head->next;
RandomListNode* newHead = new RandomListNode(head->label);
newHead->random = head;
RandomListNode* current = head->next;
head->next = newHead;
RandomListNode* newCurrent = newHead;
RandomListNode* oldCurrent = current;
while(current){
newCurrent->next = new RandomListNode(current->label);
newCurrent->next->random = current;
newCurrent = newCurrent->next;
storage[current] = current->next;
current = current->next;
oldCurrent->next = newCurrent;
oldCurrent = current;
}
newCurrent = newHead;
while(newCurrent){
if(!newCurrent->random->random){
newCurrent->random = NULL;
}
else{
newCurrent->random = newCurrent->random->random->next;
}
newCurrent = newCurrent->next;
}
current = head;
for(int i=1;i<storage.size();i++){
current->next = storage[current];
current = current->next;
}
current->next = NULL;
return newHead;
}
};