剑指offer-复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
考虑分三步来复制复杂链表:
- 遍历原始链表,把复制结点插入到其对应的原始节点之后;
- 遍历链表,对存在random指针的原始结点,让其复制节点也就是next指向的节点的random指针,指向原始节点random指针指向结点的复制节点,也就是其next指针指向的节点;
- 把新链表拆分成原始链表和复制链表:奇数位置的节点连起来为原始链表,偶数位置的节点连起来为复制链表。
代码
1 /* 2 struct RandomListNode { 3 int label; 4 struct RandomListNode *next, *random; 5 RandomListNode(int x) : 6 label(x), next(NULL), random(NULL) { 7 } 8 }; 9 */ 10 class Solution { 11 public: 12 RandomListNode* Clone(RandomListNode* pHead) 13 { 14 CloneNodes(pHead); 15 ConnectRandomNodes(pHead); 16 return ReconnectNodes(pHead); 17 } 18 void CloneNodes(RandomListNode* pHead){ 19 RandomListNode* pNode=pHead; 20 while(pNode){ 21 RandomListNode* pClone=new RandomListNode(pNode->label); 22 pClone->next=pNode->next; 23 pNode->next=pClone; 24 pNode=pClone->next; 25 } 26 } 27 void ConnectRandomNodes(RandomListNode* pHead){ 28 RandomListNode* pNode=pHead; 29 while(pNode){ 30 if(pNode->random) 31 pNode->next->random=pNode->random->next; 32 pNode=pNode->next->next; 33 } 34 } 35 RandomListNode* ReconnectNodes(RandomListNode* pHead){ 36 RandomListNode* pNode=pHead; 37 RandomListNode* pCloneHead=NULL; 38 RandomListNode* pCloneNode=NULL; 39 if(pNode){ 40 pCloneHead=pCloneNode=pNode->next; 41 pNode->next=pCloneNode->next; 42 pNode=pNode->next; 43 } 44 while(pNode){ 45 pCloneNode->next=pNode->next; 46 pCloneNode=pCloneNode->next; 47 pNode->next=pCloneNode->next; 48 pNode=pNode->next; 49 } 50 return pCloneHead; 51 } 52 };