题目:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
复杂链表的类:
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
示例:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null
对于普通链表的复制,直接遍历链表,每轮对当前节点的值以及指向下一节点的指针进行复制即可。但本题中加入了random指针,它可以指向任意节点或null,在遍历过程中可能还没遍历到random指针所指的节点,因此无法对其进行复制等操作。
一种解题思路是:由于random指针的存在,因此要求随时能访问链表中的任意节点,可用哈希表(在C++的STL中为unordered_map)来实现。初始化哈希表:
map[head]=new Node(head->val);
head = head->next;
如此一来,便建立起了初始链表和新链表的对应关系,新链表中。每个节点的生成都使用了Node类的构造函数,其中新节点对应参数的值为:
map[x]->val = x->val;
map[x]->next = nullptr;
map[x]->random = nullptr;
接下来,将初始链表中的每个节点对应的两个指针next和random赋给新链表对应的节点:
map[head]->next=map[head->next];
map[head]->random=map[head->random];
head = head->next;
最后返回新链表头节点地址map[head]即可。
最终代码:
#include<iostream>
#include<unordered_map>
using namespace std;
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
class Solution {
private:
unordered_map<Node*, Node*> map;
public:
Node* copyRandomList(Node* head) {
Node* temp = head;
while (temp != nullptr) {
map[temp] = new Node(temp->val);
temp = temp->next;
}
temp = head;
while (temp != nullptr) {
map[temp]->next = map[temp->next];
map[temp]->random = map[temp->random];
}
return map[head];
}
};