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

 

posted @ 2014-04-05 13:34  Eason Liu  阅读(4297)  评论(3编辑  收藏  举报