A linked list is given such that each node contains an additional random pointer which cocould point to any node in the list or null.
Return a deep copy of the list.
Idea: This question requires copying the linked list. Because each element has a random pointer, the problem becomes a little more complicated.
Method 1: first, copy the current node and map the address of the current node and the address of the new node to the map. Then, repeat the page to find the map, find the address of the current node and its next and random pointer corresponding to the new node, and modify the next and Random Fields of the new node corresponding to the current node.
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( !head ) { return 0; } 5 unordered_map<RandomListNode*,RandomListNode*> addrMap; 6 RandomListNode *curr = head; 7 while( curr ) { 8 addrMap[curr] = new RandomListNode( curr->label ); 9 curr = curr->next;10 }11 curr = head;12 while( curr ) {13 RandomListNode *newCurr = addrMap[curr];14 if( curr->next ) { newCurr->next = addrMap[curr->next]; }15 if( curr->random ) { newCurr->random = addrMap[curr->random]; }16 curr = curr->next;17 }18 return addrMap[head];19 }20 };
The preceding method completes replication and may need to search for each node three times.
Method 2: similar to method 1, map is also used to record the address ing relationship between the original node and the new node. The difference is that the copy of the normal linked list has been completed for the first time, but the random field of the new node is the same as that of the original node. Therefore, for the second time, modify the random field of the new node by searching the map.
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( head == 0 ) { return 0; } 5 map<RandomListNode*,RandomListNode*> addrMap; 6 RandomListNode *newhead = new RandomListNode(head->label), *node = newhead; 7 node->random = head->random; addrMap[head] = node; 8 while( head->next ) { 9 head = head->next;10 node->next = new RandomListNode(head->label);11 node = node->next;12 node->random = head->random;13 addrMap[head] = node;14 }15 node = newhead;16 while( node ) {17 if( node->random ) {18 node->random = addrMap[node->random];19 }20 node = node->next;21 }22 return newhead;23 }24 };
Compared with method 1, this method only needs to perform one search for each node on map. However, the first traversal of the loop body is more complex than method 1. Both method 1 and method 2 need to use map to record the address ing between the original node and the new node.
Method 3: The replication process is completed by traversing three times without using map to store the address ing relationship.
During the first traversal, the original node's random field is directed to the address of the new node, and the original value of the random field is stored in the label field of the new node, to map the original and new nodes. This allows us to find the corresponding new node through the random field of the original node, which is the same as creating an address ing relationship using map.
In the second traversal, the random field and next field of the new node are modified through the above ing relationship to point to the corresponding new node.
In the third traversal, modify the label field of the new node and restore the random field of the original node.
1 class Solution { 2 public: 3 RandomListNode *copyRandomList( RandomListNode *head ) { 4 if( head == 0 ) { return 0; } 5 RandomListNode *node = head; 6 // first loop: new all nodes. 7 while( node ) { 8 RandomListNode *newNode = new RandomListNode( (int)node->random ); 9 node->random = newNode;10 node = node->next;11 }12 // second loop: assign random and next pointer.13 node = head;14 while( node ) {15 RandomListNode *newNode = node->random;16 RandomListNode *random = (RandomListNode*)newNode->label;17 if( random ) {18 newNode->random = random->random;19 }20 if( node->next ) {21 newNode->next = node->next->random;22 }23 node = node->next;24 }25 // third loop: recover ramdom pointer and copy label.26 node = head;27 RandomListNode *newHead = head->random;28 while( node ) {29 RandomListNode *newNode = node->random;30 node->random = (RandomListNode*)newNode->label;31 newNode->label = node->label;32 node = node->next;33 }34 return newHead;35 }36 };