题目大意:深拷贝一个链表,链表除了含有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;