复杂链表的复制
来源:互联网 发布:app刷榜软件 编辑:程序博客网 时间:2024/06/10 05:39
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
方法一:map关联
首先遍历一遍原链表,创建新链表(赋值label和next),用map关联对应结点;再遍历一遍,更新新链表的random指针。(注意map中应有NULL ----> NULL的映射),哈希表会消耗空间O(N)
方法二:next指针关联
创建新链表的时候,用原结点的next指针指向对应新结点,新结点的next指针指向下一个原结点,以此类推,形成之字形关联。然后,就可以先更新新链表的random指针,再解除next关联,更新next指针。这种方法不需要map来辅助,不管查找next还是random指针都是O(1)的,效率很高。
/*struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { }};*/class Solution {public: //复制原始链表的任一节点N并创建新节点N',再把N'链接到N的后边 void CloneNodes(RandomListNode* pHead) { RandomListNode* pNode=pHead; while(pNode!=NULL) { RandomListNode* pCloned=new RandomListNode(0); pCloned->label=pNode->label; pCloned->next=pNode->next; pCloned->random=NULL; pNode->next=pCloned; pNode=pCloned->next; } } //如果原始链表上的节点N的random指向S,则对应的复制节点N'的random指向S的下一个节点S' void ConnectRandomNodes(RandomListNode* pHead) { RandomListNode* pNode=pHead; while(pNode!=NULL) { RandomListNode* pCloned=pNode->next; if(pNode->random!=NULL) pCloned->random=pNode->random->next; pNode=pCloned->next; } } //把得到的链表拆成两个链表,奇数位置上的结点组成原始链表,偶数位置上的结点组成复制出来的链表 RandomListNode* ReConnectNodes(RandomListNode* pHead) { RandomListNode* pNode=pHead; RandomListNode* pClonedHead=NULL; RandomListNode* pClonedNode=NULL; //初始化 if(pNode!=NULL) { pClonedHead=pClonedNode=pNode->next; pNode->next=pClonedNode->next; pNode=pNode->next; } //循环 while(pNode!=NULL) { pClonedNode->next=pNode->next; pClonedNode=pClonedNode->next; pNode->next=pClonedNode->next; pNode=pNode->next; } return pClonedHead; } //三步合一 RandomListNode* Clone(RandomListNode* pHead) { CloneNodes(pHead); ConnectRandomNodes(pHead); return ReConnectNodes(pHead); }};
阅读全文