且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

[LeetCode] Copy List with Random Pointer

更新时间:2022-07-06 19:15:42

Well, since we need to make a deep copy of the list and nodes in the list have a random pointer that may point to any node in the list (or NULL), we need to maintain a mapping from each node in the origianl list to the node in the copy list. If the copy of a node already exists, just use that copy without copying it again; otherwise, create a new copy and add it to the mapping.

The following code is pretty straight-forward.

 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head) {
 4         if (!head) return NULL;
 5         mp[head] = new RandomListNode(head -> label);
 6         RandomListNode* run = head;
 7         RandomListNode* temp = mp[head];
 8         while (run) {
 9             /* Process the next pointer */
10             if (run -> next) {
11                 if (mp.find(run -> next) == mp.end())
12                     mp[run -> next] = new RandomListNode(run -> next -> label);
13                 temp -> next = mp[run -> next];
14             }
15             /* Process the random pointer */
16             if (run -> random) {
17                 if (mp.find(run -> random) == mp.end())
18                     mp[run -> random] =  new RandomListNode(run -> random -> label);
19                 temp -> random = mp[run -> random];
20             }
21             run = run -> next;
22             temp = temp -> next;
23         }
24         return mp[head];
25     }
26 private:
27     unordered_map<RandomListNode*, RandomListNode*> mp;
28 };

This code also has a very concise and easy-to-understand recursive solution as follows.

 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head) {
 4         if (!head) return NULL;
 5         if (mp.find(head) != mp.end())
 6             return mp[head];
 7         RandomListNode* node = new RandomListNode(head -> label);
 8         mp[head] = node;
 9         node -> next = copyRandomList(head -> next);
10         node -> random = copyRandomList(head -> random);
11         return mp[head];
12     }
13 private:
14     unordered_map<RandomListNode*, RandomListNode*> mp;
15 };

This link has a clever solution using O(1) extra space, which is rewritten below in C++.

 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head) {
 4         if (!head) return NULL;
 5         RandomListNode* run = head;
 6         /* Insert the copy of each node after it. */
 7         while (run) {
 8             RandomListNode* copy = new RandomListNode(run -> label);
 9             copy -> next = run -> next;
10             run -> next = copy;
11             run = run -> next -> next;
12         }
13         /* Set the random pointer for each copy. */
14         run = head;
15         while (run) {
16             if (run -> random)
17                 run -> next -> random = run -> random -> next;
18             run = run -> next -> next;
19         }
20         /* Extract the copy list. */
21         RandomListNode* new_head = new RandomListNode(0);
22         RandomListNode* new_run;
23         run = head;
24         new_head -> next = head -> next;
25         while (run) {
26             new_run = run -> next;
27             run -> next = new_run -> next;
28             if (run -> next)
29                 new_run -> next = new_run -> next -> next;
30             run = run -> next;
31         }
32         return new_head -> next;
33     }
34 };