当前位置:编程学习 > 网站相关 >>

LeetCode:Copy List with Random Pointer

题目大意:深拷贝一个链表,链表除了含有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;
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,