title: 2019-8-22 复杂链表复制
tags: 算法,每日一题,链表
复杂链表的复制
1. 题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
2.题目解析
这道题的难点是有一个每一个节点都有一个指向随机位置节点的指针,所以在复制的时候就不好确定这个随机指针对应的位置。既然不好确定那我们就要想办法把它确定。
2.1 思路解析
因为存在随机指针,所以我们无法按照链表顺序依次进行复制。因此我们需要先将所有的节点都复制出来,然后建立原节点与复制节点的映射关系,然后再遍历一遍原链表将复制节点连接就可以得到复制结果了。
建立映射有两种方式:
方案一:使用一个map建立原节点与复制节点的映射。
方案二:将复制的节点挂在原节点之后。
/*
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 pHead; //这个要加上
return Clone2(pHead);
}
RandomListNode* Clone1(RandomListNode* pHead){//使用map的方式构建原节点与复制节点的映射
RandomListNode* head = pHead;
unordered_map<RandomListNode*, RandomListNode*> ori_copy_map;
//1、构建映射关系
while(head != NULL){
ori_copy_map.insert(make_pair(head, new RandomListNode(head->label) )); //这里必须使用make_pair
head = head->next;
}
//2、构建复制的链接
head = pHead;
while(head != NULL){
if (ori_copy_map[head->next]) ori_copy_map[head]->next = ori_copy_map[head->next];
if (ori_copy_map[head->random]) ori_copy_map[head]->random = ori_copy_map[head->random];
head = head->next;
}
return ori_copy_map[pHead];
}
RandomListNode* Clone2(RandomListNode* pHead){//将复制节点放在原节点后面的方式构建映射
RandomListNode* head = pHead;
//1、复制原节点
while(head != NULL){
RandomListNode* new_node = new RandomListNode(head->label);
new_node->next = head->next;
head->next = new_node;
head = new_node->next;
}
//2、构建随机节点
head = pHead;
RandomListNode* new_head = pHead->next;
while(head != NULL){
if (head->random) head->next->random = head->random->next;
head = head->next->next;
}
//3、拆分
head = pHead;
while(head->next != NULL){ //这里要判断next
RandomListNode* temp = head->next;
head->next = temp->next;
head = temp;
}
return new_head;
}
};
更多关于编程和机器学习资料请关注FlyAI公众号。