题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
分析1:
我们可以依次遍历这个链表,用一个哈希结构<Node*,Node*>来存储每个节点与新构建的节点的关系,这样一来,新节点的的指针域就可以从键域的指针域来获得。
如:1->2->3, 哈希结构为(1,1) (2,2) (3,3),
Node* tmp = head;
mmap[tmp]->next=mmap[tmp->next];
mmap[tmp]->random = mmap[tmp->random];
代码1:
unordered_map<Node*,Node*> mmap;
Node* copy(Node* head)
{
for(Node *tmp = head;tmp != NULL;tmp = tmp->next)
{
mmap[tmp] = new Node(tmp->val); //构建新的节点
}
for(Node *tmp = head;tmp != NULL;tmp = tmp->next)
{
mmap[tmp]->next = mmap[tmp->next];//新的节点的指针域根据键域来获得
mmap[tmp]->random = mmap[tmp->random];
}
return mmap[head];
}
Node* copyRandomList(Node* head)
{
if(head == NULL) return NULL;
return copy(head);
}
分析2:
如果用哈希表来存储节点与新节点的关系,空间复杂度就为O(n),如果我们原地构建链表即不使用额外空间,我们可以在遍历链表的过程中,在每个节点的后面创建一个新的节点,然后ptr=ptr->next->next来遍历原链表,在建立完之后我们再从头到尾遍历一次旧节点,新节点的指针域根据对应的旧节点的指针域来获得,最后分开旧链表与新链表
- 遍历旧链表,并在每个节点后面创建一个新的节点
- 构建新节点的random指针域
- 分开旧链表与新链表----完成新节点的next域的构建
代码2:
Node* copy(Node* head)
{
/在原链表基础下拷贝
Node* cur = head;
while(cur != NULL)
{
Node* copyNode = new Node(cur->val);
copyNode->next = cur->next;
cur->next = copyNode;
cur = cur->next->next;
}
/将拷贝出来的random进行指向
cur = head;
while(cur != NULL)
{
if(cur->random != NULL)
{
cur->next->random = cur->random->next;
}
cur = cur->next->next;
}
/分离原链表与拷贝出来的链表
Node* copyhead = head->next;
cur = head;
Node* curcopy = head->next;
while(cur != NULL)
{
cur->next = cur->next->next;
cur = cur->next;
if(curcopy->next != NULL) //如果不是最后一个
{
curcopy->next = curcopy->next->next;
curcopy = curcopy->next;
}
}
return copyhead;
}
Node* copyRandomList(Node* head)
{
if(head == NULL) return NULL;
return copy(head);
}
注意事项:
我们不能使新节点的next指针与random指针指向旧链表中的节点!
下面是错误的做法
unordered_map<Node*,Node*> mmap; //记录节点与节点随机指针的映射关系
Node* copy(Node *head)
{
Node* ptr = head;
Node* newptr = new Node(0);
Node* pp = newptr;
while( ptr != NULL )
{
mmap[pp] = ptr->random; //在这里新节点的random指向的是旧链表中的节点,
并没有构造出新的节点
pp = pp->next;
ptr = ptr->next;
}
Node* ppp = newptr;
while(ppp != NULL)
{
ppp->random = mmap[ppp];
ppp = ppp->next;
}
return newptr;
}
Node* copyRandomList(Node* head)
{
if(head == NULL) return NULL;
return copy(head);
}