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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM