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 };