标签:
前半部分 转载出处:http://www.cnblogs.com/TenosDoIt/p/3387000.html
题目大意:深拷贝一个链表,链表除了含有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)
算法2的C++实现:
1 /** 2 * Definition for singly-linked list with a random pointer. 3 * struct RandomListNode { 4 * int label; 5 * RandomListNode *next, *random; 6 * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 RandomListNode *copyRandomList(RandomListNode *head) { 12 //在原来每个结点之后插入一个副本结点 13 RandomListNode* cur = head; 14 while (cur) { 15 RandomListNode* newNode = new RandomListNode(cur -> label); 16 newNode -> next = cur -> next; 17 cur -> next = newNode; 18 cur = newNode -> next; 19 } 20 //构造每个新结点的random指针 21 cur = head; 22 while (cur) { 23 if (cur -> random) 24 cur -> next -> random = cur -> random -> next; 25 cur = cur -> next -> next; 26 } 27 //分离新旧链表 28 RandomListNode result(0); 29 RandomListNode *p = &result; 30 cur = head; 31 while (cur) { 32 p -> next = cur -> next; 33 p = p -> next; 34 cur -> next = cur -> next -> next; 35 cur = cur -> next; 36 } 37 return result.next; 38 } 39 };
Copy List with Random Pointer解法
标签:
原文地址:http://www.cnblogs.com/darrensun/p/4534583.html