題目地址: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