题目大意:深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向字符串中的某个节点或者为空。
节点定义为:
struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};
假设原始链表如下,细线表示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
1 RandomListNode *copyRandomList(RandomListNode *head) { 2 if(!head) return NULL; 3 map<RandomListNode*,RandomListNode*>oldlist;//保存原始链表指针关系。 4 RandomListNode *result=new RandomListNode(head->label); 5 RandomListNode *pnew=result; 6 RandomListNode *pold=head; 7 pnew->random=pold; 8 RandomListNode *pnewpre=pnew; 9 RandomListNode *poldpre=pold; 10 //保存原始指针。 11 while(pold->next){ 12 oldlist.insert(make_pair(pold,pold->next)); 13 pold=pold->next; 14 pnew=new RandomListNode(pold->label); 15 poldpre->next=pnewpre; 16 pnewpre->next=pnew; 17 pnew->random=pold; 18 19 poldpre=pold; 20 pnewpre=pnew; 21 } 22 pold->next=pnew;//oldlist最后一个节点 23 //设置new list 的random指针 24 pnew=result; 25 while(pnew){ 26 if(pnew->random->random) pnew->random=pnew->random->random->next; 27 else pnew->random=NULL; 28 pnew=pnew->next; 29 } 30 //恢复old list 的next指针 31 pold=head; 32 for(int i=0;i<oldlist.size();i++){ 33 pold->next=oldlist[pold]; 34 pold=pold->next; 35 } 36 pold->next=NULL; 37 return result; 38 } 39 }