输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
借鉴剑指offer,如果用哈希表,将老节点与新节点一一对应起来,用空间换时间,时间复杂度是O(n),但是空间超限:
/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if(pHead==NULL) return NULL; map<RandomListNode*,RandomListNode*> hash; RandomListNode* q=pHead; RandomListNode* head=new RandomListNode(0); RandomListNode* p=head; while(q){ RandomListNode* tmp=new RandomListNode(q->label); hash[q]=tmp; p->next=tmp; p=p->next; } head=head->next; p=head; q=pHead; while(p){ p->random=hash[q->random]; p=p->next; q=q->next; } return head; } };
所以用第二个思路,分为三步:
具体实现:
/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if(pHead==NULL) return NULL; RandomListNode* p=pHead; RandomListNode* head=new RandomListNode(0); RandomListNode* q=head; //把新生成的节点链接在原链表对应节点的后边 while(p){ RandomListNode* tmp=p->next; RandomListNode* newNode=new RandomListNode(p->label); newNode->next=tmp; p->next=newNode; p=tmp; } //新节点的random指针指向原节点的random指向的节点的下一个 p=pHead; while(p){ if(p->random) p->next->random=p->random->next; else p->next->random=NULL; p=p->next->next; } //分离新链表,并从原链表中删除新节点 p=pHead; while(p){ q->next=p->next; p=p->next=p->next->next; q=q->next; } head=head->next; return head; } };