138. Copy List with Random Pointer**

​https://leetcode.com/problems/copy-list-with-random-pointer/​

题目描述

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

The Linked List is represented in the input/output as a list of ​​n​​​ nodes. Each node is represented as a pair of ​​[val, random_index]​​ where:

  • ​val​​​: an integer representing​​Node.val​
  • ​random_index​​​: the index of the node (range from​​0​​​ to​​n-1​​​) where random pointer points to, or​​null​​ if it does not point to any node.

Example 1:

138. Copy List with Random Pointer**_leetcode

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]

Example 2:

138. Copy List with Random Pointer**_链表_02

Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]

Example 3:

138. Copy List with Random Pointer**_leetcode_03

Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]

Example 4:

Input: head = []
Output: []
Explanation: Given linked list is empty (null pointer), so return null.

Constraints:

  • ​-10000 <= Node.val <= 10000​
  • ​Node.random​​​ is​​null​​ or pointing to a node in the linked list.
  • Number of Nodes will not exceed 1000.

C++ 实现 1

这道题感觉做了好多遍, 好像 “剑指Offer” 上也有这道题. 思路是: 访问链表中的每个节点 ​​root​​​, 产生一个值相同的新节点 ​​p​​​, 同时保存 ​​root -> p​​​ 的映射关系, 在这一步不考虑 ​​random​​​, 只考虑 ​​next​​​. 这样就可以重建一个新的链表, 但 ​​random​​ 还没有指向正确的节点.

下一步遍历新链表, 通过映射关系更新新链表中的 ​​random​​ 的最终指向.

/*
// 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) {
if (!head) return nullptr;
unordered_map<Node*, Node*> record;
auto root = head;
auto dummy = new Node(0);
auto p = dummy;
while (root) {
p->next = new Node(root->val);
p = p->next;
record[root] = p;
root = root->next;
}
p = dummy->next;
root = head;
while (p) {
p->random = record[root->random];
root = root->next;
p = p->next;
}
return dummy->next;
}
};