剑指OFFER 复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
分析
设A为被复制的链表,B为复制成功的链表,由于涉及到两个链表,A的random结点会指向A的结点,而B的结点在初始是还没有创建的,B的random结点指向什么地方是无法预料的(需要根据A的相对位置来确定,而B本身不完整),所以,为了方便思考还是先把B的整体创建出来,再去补random结点的内容. (在创建的时候记录下A与B的映射关系)
代码
/*
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* old_node = pHead;
RandomListNode* new_node = NULL;
RandomListNode* last_new_node = NULL;
map<RandomListNode*,RandomListNode*>m;
while(old_node != NULL){
new_node = (RandomListNode*)malloc(sizeof(RandomListNode));
new_node->label = old_node->label;
new_node->next = NULL;
new_node->random = NULL;
if(last_new_node != NULL)last_new_node->next = new_node;
last_new_node = new_node;
//make map
m[old_node] = new_node;
m[new_node] = old_node;
old_node = old_node->next;
}
//assign values to random pointers
new_node = m[pHead];
old_node = pHead;
while(old_node != NULL){
if(old_node->random != NULL){
m[old_node]->random = m[old_node->random];
}
old_node = old_node->next;
}
return m[pHead];
}
};