# Sword finger Offer 35. Copy of complex linked list

Sword finger Offer 35. Copy of complex linked list
Please implement the copyRandomList function to copy a complex linked list. In a complex linked list, each node has a next pointer to the next node and a random pointer to any node or null in the linked list.

Example 1:

Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
Example 2:

Output: [[1,1], [2,1]]
Example 3:

Output: [[3,null],[3,0],[3,null]]
Example 4:

Output: []
Explanation: the given linked list is null (null pointer), so null is returned.

Tips:

-10000 <= Node.val <= 10000
Node.random is empty (null) or points to a node in the linked list.
The number of nodes shall not exceed 1000.

Method 1: hash table
Using the query characteristics of hash table, consider building the key value pair mapping relationship between the original linked list node and the corresponding node of the new linked list, and then traverse the next and random reference points of each node of the new linked list.

Algorithm flow:
Initialization: hash table dic, node cur points to the header node;
Create a new node and add key value pairs to dic (original cur node, new cur node);
cur traverses to the next node in the original linked list;
The reference to build a new linked list points to:
Build the next and random references of the new node;
cur traverses to the next node in the original linked list;
Complexity analysis:
Time complexity O(N): traverse the linked list in two rounds, using O(N) time.
Spatial complexity O(N): the hash table dic uses additional space of linear size.

```class Solution {
public:
unordered_map<Node*, Node*> map;
// 3. Copy each node and create a Map mapping of "original node - > new node"
while(cur != nullptr) {
map[cur] = new Node(cur->val);
cur = cur->next;
}
// 4. Build the next and random points of the new linked list
while(cur != nullptr) {
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
}
};
```

Method 2: splicing + splitting
Consider building a spliced linked list of original node 1 - > new node 1 - > original node 2 - > new node 2 - >... So that you can find the new random pointing node corresponding to the new node while accessing the random pointing node of the original node.

Algorithm flow:
Copy each node to build a splicing linked list:

Let the original linked list be node1 → node2 →... And the constructed splicing linked list is as follows:

node1→node1new→node2→node2new →⋯

The random direction of each node of the new linked list:

When accessing the random pointing node cur.random of the original node cur, the random pointing node corresponding to the new node cur.next is cur.random.next.
Split the original / new linked list:

Set pre / cur to point to the original / new chain header node respectively, and perform pre.next = pre.next.next and cur.next = cur.next.next to separate the two linked lists.

Complexity analysis:
Time complexity O(N): three rounds of traversal of the linked list, using O(N) time.
Space complexity O(1): node reference variables use additional space of constant size.

```class Solution {
public:
// 1. Copy each node and build a splicing linked list
while(cur != nullptr) {
Node* tmp = new Node(cur->val);
tmp->next = cur->next;
cur->next = tmp;
cur = tmp->next;
}
// 2. Build the random direction of each new node
while(cur != nullptr) {
if(cur->random != nullptr)
cur->next->random = cur->random->next;
cur = cur->next->next;
}
// 3. Split two linked lists
while(cur->next != nullptr) {
pre->next = pre->next->next;
cur->next = cur->next->next;
pre = pre->next;
cur = cur->next;
}
pre->next = nullptr; // Handle the original end node of the linked list separately