两种方法,都要扫描两遍以上
1. map法:
1)遍历原List,进行普通的copy List,把random域当作数据,和data域一样,一并copy,同时维护map,把被copy的结点地址和新结点地址关联起来。
2)遍历新List,random域的值作为key 查map,得到对应新list的结点地址,random域更新为这个结点地址。
2. 先插入在分拆法:好处是不用map,把新节点插在原结点之后,这样等于也维护了新旧结点的关联关系。
1)遍历原List,创建对应结点插在原结点后,得到一个长2n的的List
2)遍历List,更新random域,
3)分拆List
RandomListNode *copyRandomList(RandomListNode *head) {
for(RandomListNode *cur=head;cur!=NULL;)
{
RandomListNode *node = new RandomListNode(cur->label);
node->next=cur->next;
cur->next=node;
cur=node->next;
}
for(RandomListNode *cur=head;cur!=NULL;)
{
if(cur->random)
cur->next->random= cur->random->next;
cur=cur->next->next;
}
RandomListNode dummy(-1);
for(auto p=head,prev=&dummy;p;p=p->next)
{
prev->next=p->next;
prev=prev->next;
p->next=p->next->next;
}
return dummy.next;
}