题目
复制带有随机指针的链表:一个单链表除了next指针外还有一个random指针随机指向任何一个元素(可能为空)
《剑指offer》上的面试题26
分析
方法一:
map<旧地址,新地址>,先按普通方法复制链表,再两个链表同时走复制random(旧节点a,新节点a’)a'->random=map[a->random]
(空指针单独处理)
方法二:
插入:每个节点后面插入一个自身的“复本”
复制random指针:一个旧节点a的复本是a->next, a->random的复本是a->random->next,新节点的random指针a->next->random = a->random->next(空指针单独处理)
拆分:旧节点链表是奇数项,新节点链表是偶数项。
方法二代码
/**
* 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) {
if(head==NULL){
return NULL;
}
RandomListNode *now = head; //复制各个节点
while(now){
RandomListNode *copy = new RandomListNode(now->label);
copy->next = now->next;
now->next = copy;
now = copy->next;
}
for(now=head; now; now=now->next->next){ //复制random指针域
now->next->random = (now->random)?now->random->next:NULL;
}
RandomListNode* h = head->next; //断开成两个链表
RandomListNode* t = h;
RandomListNode* tail = head;
for(;;){
tail->next = t->next;
tail = tail->next;
if(tail==NULL){
break;
}
t->next = tail->next;
t = t->next;
}
return h;
}
};