题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
对此问题,每个指针节点存在两个链域,一个指向下一节点,另一个指向任意节点。首要需要完成的是对节点进行复制,然后对复制后的节点间的指向关系进行复制。
此问题分为三步来解决,时间复杂度为O(n):
step1:在原节点基础上,对每个节点进行复制,并将复制节点插入被复制节点之后。
step2:由于复制节点是被复制节点的滞后一个单位位置的点,所以当被复制节点存在一个特殊指针指向某一节点时,复制节点也应执行相同操作,而复制节点特殊指针的指向,一定是被复制节点特殊指针指向节点的下一个节点元素,按此规则对链表中所有节点进行遍历,完成特殊指针指向复制。
setp3:将原链表与复制链表分离,由于原链表与复制链表的元素交叉相连,所以直接按照交替顺序遍历就可实现两个链表的分离。
C++代码实现如下:
/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { clone1(pHead); clone2(pHead); RandomListNode* head= clone3(pHead); return head; } void clone1(RandomListNode* pHead){ //step1: 逐个复制列表元素,并重新复制一个链表 if(pHead==NULL){ return; } RandomListNode* pNode=pHead; while(pNode!=NULL){ RandomListNode* newNode=new RandomListNode(pNode->label); newNode->next=pNode->next; pNode->next=newNode; pNode=newNode->next; } } void clone2(RandomListNode* pHead){ //step2:设置随机指针的指向 if(pHead==NULL){ return; } RandomListNode* pNode=pHead; while(pNode!=NULL){ RandomListNode* pNode2=pNode->next; if(pNode->random!=NULL){ pNode2->random=pNode->random->next; } pNode=pNode2->next; } } RandomListNode* clone3(RandomListNode* pHead){ if(pHead==NULL){ return NULL; } RandomListNode* pNode1=pHead; RandomListNode* Head2=pNode1->next; RandomListNode* pNode2=pNode1->next; pNode1->next=pNode2->next; pNode1=pNode1->next; while(pNode1!=NULL){ pNode2->next=pNode1->next; pNode2=pNode2->next; pNode1->next=pNode2->next; pNode1=pNode1->next; } return Head2; } };