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