Problem:
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.
这个问题的关键就在于random指针如何完成拷贝,next指针一次遍历就完成了,random指针拷贝的关键在于,如何找到random指向的节点对应的新的节点。下面介绍一个巧妙的方法:
-
对oldlist中的节点,依次作如下的操作:对于第i个节点oldnode[i],生成拷贝节点copynode[i],并且插入在oldnode[i]和oldnode[i+1]之间,最后一个节点直接附加到oldlist后面即可。
-
处理每一个copynode的random拷贝,及对每一个copynode=oldnode.next, oldnode.next.random=oldnode.random.next 后面的next确保是copynode。
-
通过如下的操作,恢复oldlist,以及生成copylist 1) oldnode.next = oldnode.next.next 2) copynode.next = copynode.next.next 这里要注意,oldnode的最后一个节点,next是null
注意题目中的random可能指向null,在上面第2步的时候处理一下就可以了。
code:
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head==NULL) return NULL;
RandomListNode *p=head,*newhead=NULL,*rear=NULL,*q=NULL;
while(p)
{
rear=p->next;
q=new RandomListNode(p->label);
q->next=p->next;
p->next=q;
p=rear;
}
p=head;
newhead=head->next;
while(p)
{
if(p->random)
p->next->random=p->random->next;
p=p->next->next;
}
p=head;
q=newhead;
while(q->next)//note the NULL->next problem
{
rear=q->next;
p->next=q->next;
q->next=rear->next;
p=rear;
q=p->next;
}
p->next=NULL;
q->next=NULL;
return newhead;
}
};