本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

LeetCode:Copy List with Random Pointer

题目地址:here

题目大意:深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向字符串中的某个节点或者为空。

节点定义为:

struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};

假设原始链表如下,细线表示next指针,粗线表示random指针,没有画出的指针均指向NULL:

算法1:我们在构建新链表的节点时,保存原始链表的next指针映射关系,并把指针做如下变化(蓝色为原始链表节点,紫红色为新链表节点):

然后在上图的基础上进行如下两步

1、构建新链表的random指针:比如new1->random = new1->random->random->next, new2->random = NULL, new3-random = NULL, new4->random = new4->random->random->next

2、恢复原始链表:根据最开始保存的原始链表next指针映射关系恢复原始链表

该算法时间空间复杂度均为O(N)


算法2:该算法更为巧妙,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:

同理分两步

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代码:

 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head)
 4      {
 5         // Note: The Solution object is instantiated only once and is reused by each test case.
 6         if(head == NULL)return NULL;
 7         std::map<RandomListNode *,RandomListNode *> oldlistMap;
 8         RandomListNode *result = new RandomListNode(head->label) ;
 9         RandomListNode *pold = head, *pnew = result;
10         pnew->random = pold;
11         //pold->next = pnew;
12         RandomListNode* poldPre = pold, *pnewPre = pnew;
13         while(pold->next != NULL)
14         {
15             //保存old list的next指针
16             oldlistMap.insert(std::map<RandomListNode*,
17                               RandomListNode*>::value_type(pold, pold->next));
18             pold = pold->next;
19             poldPre->next = pnew;
20             pnew = new RandomListNode(pold->label);
21             pnewPre->next = pnew;
22             pnew->random = pold;
23 
24             poldPre = pold;
25             pnewPre = pnew;
26         }
27         pold->next = pnew;//设置old list最后一个节点
28 
29         //设置new list的random指针
30         pnew = result;
31         while(pnew != NULL)
32         {
33             if(pnew->random->random)
34                 pnew->random = pnew->random->random->next;
35             else pnew->random = NULL;
36             pnew = pnew->next;
37         }
38         //恢复old list的next指针
39         pold = head;
40         for(int i = 1; i <= oldlistMap.size(); i++)
41         {
42             pold->next = oldlistMap[pold];
43             pold = pold->next;
44         }
45         pold->next = NULL;//old list 最后一个节点
46 
47         return result;
48     }
49 };
 1 class Solution {
 2 public:
 3     RandomListNode *copyRandomList(RandomListNode *head)
 4      {
 5         // Note: The Solution object is instantiated only once and is reused by each test case.
 6         if(head == NULL)return NULL;
 7         RandomListNode *result = NULL;
 8         RandomListNode *pold = head, *pnew = result, *poldNext = NULL;
 9         do
10         {
11             poldNext = pold->next;
12             pnew = new RandomListNode(pold->label);
13             pold->next = pnew;
14             pnew->next = poldNext;
15 
16             if(result == NULL)
17                 result = pnew;
18             pold = poldNext;
19         }while(pold);
20         //设置new list的random指针
21         pold = head;
22         while(pold)
23         {
24             if(pold->random)
25                 pold->next->random = pold->random->next;
26             pold = pold->next->next;
27         }
28         //恢复old list 和new list
29         pold = head;
30         pnew = result;
31         while(pnew->next)
32         {
33             pold->next = pnew->next;
34             pold = pold->next;
35             pnew->next = pold->next;
36             pnew = pnew->next;
37         }
38         pold->next = NULL;
39         pnew->next = NULL;
40         return result;
41     }
42 };

 【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3387000.html

 

posted @ 2013-10-24 23:02  tenos  阅读(9566)  评论(1编辑  收藏  举报

本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

公益页面-寻找遗失儿童