这道题目很经典,很多书和OJ里都有。如果初次遇到,一定很难搞定。再看其解法,实在是很惊艳。
有两个可以得到深刻启示的地方:
(1)冗余的思想。谈到复制,我们往往都会另起炉灶,而不会原来链表上搞来搞去,感觉很复杂很危险,会一团糟。美错,最危险的地方就是最安全的地方。
(2)指针的步伐。这里的指针有一走两步的操作,很容易导致RE。但是否意味着每步都要仔细考虑指针越界?不然,那样程序会写的很累很乱。还是按照最初的想法,谨慎实现之。回头查看特殊情况,例如空指针情况、只有一个节点的情况,用实际用例去测试,则很容易发现那里会越界。
/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
RandomListNode *p,*q,*tmp,*newp;
if(!head) return nullptr;
//insert duplicate node
p=head;
while(p!=nullptr){
tmp = new RandomListNode(p->label);
tmp->next=p->next;
p->next=tmp;
p=tmp->next;
}
//copy random pointers
p=head;
q=p->next;
while(p!=nullptr && q!=nullptr){
if(p->random!=nullptr)
q->random=p->random->next;
if(q->next==nullptr) break;
p=q->next;
q=p->next;
}
//disconnect the duplicated
p=head;
q=p->next;
newp=q;
while(q!=nullptr){
p->next=q->next;
p=p->next;
if(q->next==nullptr) break;
q->next=p->next;
q=q->next;
}
return newp;
}
};
测试程序:
#include <iostream>
using namespace std;
struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};
RandomListNode *copyRandomList(RandomListNode *head) {
RandomListNode *p,*q,*tmp,*newp;
if(!head) return nullptr;
//insert duplicate node
p=head;
while(p!=nullptr){
tmp = new RandomListNode(p->label);
tmp->next=p->next;
p->next=tmp;
p=tmp->next;
}
//copy random pointers
p=head;
q=p->next;
while(p!=nullptr && q!=nullptr){
if(p->random!=nullptr)
q->random=p->random->next;
if(q->next==nullptr) break;
p=q->next;
q=p->next;
}
//disconnect the duplicated
p=head;
q=p->next;
newp=q;
while(q!=nullptr){
p->next=q->next;
p=p->next;
if(q->next==nullptr) break;
q->next=p->next;
q=q->next;
}
return newp;
}
int main() {
// your code goes here
int num;
RandomListNode *tmp, *p ,*head= new RandomListNode(0);
p=head;
while(p->label!=-1){
cin>>num;
tmp=new RandomListNode(num);
p->next=tmp;
p=tmp;
}
//p=head;
//while(p!=nullptr) {cout<<p->label<<" ";p=p->next;}cout<<endl;
p=copyRandomList(head);
while(p!=nullptr)
{cout<<p->label<<" ";p=p->next;}
return 0;
}