算法思想
- 哈希表Mydic映射原有节点->新的节点
- 原节点为空,则返回空
- 原节点在哈希表中可以找到,则说明新的节点已生成,直接返回
- 根据原有节点的值,创建新的节点root = Node(node.val)
- 将原有节点和新节点的对应关系添加到哈希表中Mydic[node] = root
- 最后参照原节点的next和random关系,创建新的next和random节点给新节点root
- 递归整个过程
python
# Definition for a Node.
class Node:
def __init__(self, x: int, next=None, random=None):
self.val = int(x)
self.next = next
self.random = random
class Solution:
def copyRandomList(self, head):
dic = dict()
def recursion(node):
if not node:
return node
if node in dic:
return dic[node]
root = Node(node.val)
dic[node] = root
root.next = recursion(node.next)
root.random = recursion(node.random)
return root
return recursion(head)
c++
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
Node* dummy = new Node(-1);
Node* pre = dummy;
unordered_map<int, int> index_random;
unordered_map<Node*, int> index_node;
Node* curr = head;
int index = 0;
// 记录原链表各节点位置索引
while (curr != nullptr) {
index_node[curr] = ++index;
curr = curr->next;
}
// 记录原链表各节点的random位置索引
curr = head;
index = 0;
while (curr != nullptr) {
if (curr->random == nullptr) {
index_random[++index] = -1;
} else {
index_random[++index] = index_node[curr->random];
}
curr = curr->next;
}
// 构造新链表
// 先只还原next指针,不还原random指针
curr = head;
while (curr != nullptr) {
Node* newNode = new Node(curr->val);
pre->next = newNode;
pre = pre->next;
curr = curr->next;
}
// 还原random指针
// 使用之前的random位置索引,用于遍历定位random位置
curr = dummy->next;
index = 0;
while (curr != nullptr) {
int k = index_random[++index];
if (k == -1) {
curr->random = nullptr;
} else {
Node* curr2 = dummy;
while (k != 0) {
curr2 = curr2->next;
k--;
}
curr->random = curr2;
}
curr = curr->next;
}
return dummy->next;
}
};
和python部分的代码思路一样,都是老新节点存在哈希表中,递归构建新链表。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
unordered_map<Node*, Node*> old_new_node_map;
Node* copyRandomList(Node* head) {
return recursion(head);
}
Node* recursion(Node* node) {
if (node == nullptr) return node;
if (old_new_node_map.count(node) > 0) return old_new_node_map[node];
Node* newNode = new Node(node->val);
old_new_node_map[node] = newNode;
newNode->next = recursion(node->next);
newNode->random = recursion(node->random);
return newNode;
}
};