不太熟练,拖了几天终于AC了。不过空间复杂度略高。。
struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};
RandomListNode *copyRandomList(RandomListNode *head) {
RandomListNode *cp = NULL;
vector<int> labs;
vector<RandomListNode *> randList;
if(!head)return cp;
labs.push_back(head->label);
head->label = 0;
cp = new RandomListNode(0);
int i = 0;
RandomListNode *pcp=cp, *phead=head;
//tag nodes
while(phead->next){
i++;
RandomListNode *newcp = new RandomListNode(i);
labs.push_back(phead->next->label);
pcp->next = newcp;
phead->next->label= i;
phead = phead->next;
randList.push_back(pcp);
pcp = newcp;
}
randList.push_back(pcp);
//set random points
pcp = cp;
phead = head;
RandomListNode *tmp = cp;
i = 0;
while(phead){
if(phead->random){
pcp->random = randList[phead->random->label];
}
phead = phead->next;
pcp = pcp->next;
i++;
}
//reset labels
i = 0;
pcp = cp;
phead = head;
while(phead){
phead->label = labs[i];
pcp->label = labs[i];
phead = phead->next;
pcp = pcp->next;
i++;
}
return cp;
}
leetcode上也有一些非常取巧的办法,比如利用指针地址都是连续的,然后取新链表和原链表的地址差,从而可以快速深拷贝,空间复杂度还很低:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL) return NULL;
RandomListNode *newHead = new RandomListNode(head->label);
newHead->random = head->random;
head->label = newHead - head;
RandomListNode *p = head->next, *q = newHead, *t;
while(p) {
t = new RandomListNode(p->label);
t->random = p->random;
p->label = t - p;
q->next = t;
q = t;
p = p->next;
}
q = newHead;
while(q) {
if(q->random)
q->random = q->random + q->random->label;
q = q->next;
}
p = head;
q = newHead;
while(p) {
p->label = q->label;
p = p->next;
q = q->next;
}
return newHead;
}
当然最厉害的还是重合的思想,都是奇思妙想啊:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL) return NULL;
RandomListNode *p = head;
do {
RandomListNode *q = p->next;
p->next = new RandomListNode(p->label);
p->next->next = q;
p = q;
} while(p != NULL);
p = head;
do {
p->next->random = (p->random == NULL) ? NULL : p->random->next;
p = p->next->next;
} while(p != NULL);
p = head;
RandomListNode *r = head->next;
for(RandomListNode *q = r;;) {
p->next = q->next;
p = p->next;
if(p == NULL) break;
q->next = p->next;
q = q->next;
}
return r;
}