LeetCode:Copy List with Random Pointer

題目地址:herehtml

題目大意:深拷貝一個鏈表,鏈表除了含有next指針外,還包含一個random指針,該指針指向字符串中的某個節點或者爲空。算法

節點定義爲:dom

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

假設原始鏈表以下,細線表示next指針,粗線表示random指針,沒有畫出的指針均指向NULL:3d

算法1:咱們在構建新鏈表的節點時,保存原始鏈表的next指針映射關係,並把指針作以下變化(藍色爲原始鏈表節點,紫紅色爲新鏈表節點):指針

而後在上圖的基礎上進行以下兩步code

一、構建新鏈表的random指針:好比new1->random = new1->random->random->next, new2->random = NULL, new3-random = NULL, new4->random = new4->random->random->nexthtm

二、恢復原始鏈表:根據最開始保存的原始鏈表next指針映射關係恢復原始鏈表blog

該算法時間空間複雜度均爲O(N)leetcode


算法2:該算法更爲巧妙,不用保存原始鏈表的映射關係,構建新節點時,指針作以下變化,即把新節點插入到相應的舊節點後面:

同理分兩步

一、構建新節點random指針:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next

二、恢復原始鏈表以及構建新鏈表:例如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

相關文章
相關標籤/搜索