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