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公衆號。