[Leetcode] 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.

最開始的想法就是暴力復制,時間復雜度為O(n^2),寫的時候就感覺要出現事,果不其然,超時了,后來網上看到一個O(n)的算法,非常巧妙的利用了原來鏈表的信息:

該算法更為巧妙,不用保存原始鏈表的映射關系,構建新節點時,指針做如下變化,即把新節點插入到相應的舊節點后面:
 
 
同理分兩步
 
1、構建新節點random指針:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next
 
2、恢復原始鏈表以及構建新鏈表:例如old1->next = old1->next->next,  new1->next = new1->next->next
 
該算法時間復雜度O(N),空間復雜度O(1)
 
 1 /**
 2  * Definition for singly-linked list with a random pointer.
 3  * struct RandomListNode {
 4  *     int label;
 5  *     RandomListNode *next, *random;
 6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     RandomListNode *copyRandomList(RandomListNode *head) {
12         if (head == NULL) return NULL;
13         RandomListNode *pos1 = head, *pos2 = head->next;
14         while (pos1 != NULL) {
15             pos1->next = new RandomListNode(pos1->label);
16             pos1->next->next = pos2;
17             pos1 = pos2;
18             if (pos2 != NULL)
19                 pos2 = pos2->next;
20         }
21         pos1 = head;  pos2 = head->next;
22         while (pos1 != NULL) {
23             if (pos1->random == NULL) {
24                 pos2->random = NULL;
25             } else {
26                 pos2->random = pos1->random->next;
27             }
28             pos1 = pos1->next->next;
29             if (pos2->next != NULL)
30                 pos2 = pos2->next->next;
31         }
32         RandomListNode *res = head->next;
33         pos1 = head; pos2 = head->next;
34         while(pos2->next != NULL) {
35             pos1->next = pos2->next;
36             pos1 = pos2;
37             if (pos2->next != NULL)
38                 pos2 = pos2->next;
39         }
40         pos1->next = NULL;
41         pos2->next = NULL;
42         return res;
43     }
44 };

 

下面是最開始的超時的暴力復制代碼:

 1 /**
 2  * Definition for singly-linked list with a random pointer.
 3  * struct RandomListNode {
 4  *     int label;
 5  *     RandomListNode *next, *random;
 6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     RandomListNode *copyRandomList(RandomListNode *head) {
12         if (head == NULL) return NULL;
13         RandomListNode *res = new RandomListNode(head->label);
14         RandomListNode *pos1 = head->next, *pos2 = res;
15         while (pos1 != NULL) {
16             pos2->next = new RandomListNode(pos1->label);
17             pos1 = pos1->next;
18             pos2 = pos2->next;
19         }
20         pos1 = head;  pos2 = res;
21         RandomListNode *idx1 = head, *idx2 = res;
22         while (pos1 != NULL) {
23             if (pos1->random == NULL) {
24                 pos2->random = NULL;
25             } else {
26                 idx1 = head; idx2 = res;
27                 while (pos1->random != idx1) {
28                     idx1 = idx1->next;
29                     idx2 = idx2->next;
30                 }
31                 pos2->random = idx2;
32             }
33             pos1 = pos1->next;
34             pos2 = pos2->next;
35         }
36         return res;
37     }
38 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM