剑指offer 复杂链表的复制

Posted qinduanyinghua

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer 复杂链表的复制相关的知识,希望对你有一定的参考价值。

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
1 struct RandomListNode 
2     int label;
3     struct RandomListNode *next, *random;
4     RandomListNode(int x) :
5             label(x), next(NULL), random(NULL) 
6     
7 ;

 

 
解法一:
分两步: 1、复制原始链表节点,并用next链接起来。
2、设置每个节点的random指针。假设原始链表的某个节点N的random指向节点S,由于S在链表中可能在N的前面也可能在N的后面,所以要定位S的位置需要从原始链表的头结点开始找。如果从原始链表的头结点沿着next经过s步找到节点S,那么在复制链表上节点N‘的random(记为S‘)离复制链表的头结点的距离也是沿着next指针s步。用这种方法可以为复制链表上的每个节点设置random指针。
 
时间复杂度分析:对于一个有n个节点的链表,由于定位每个节点的random都需要从链表头结点开始经过 O(n)才能找到。因此总的时间复杂度为O(n2)
 
 
解法二:解法一的时间主要花费在定位节点的random上面。为此,我们分为两步:
第一,复制原始链表上的每一个节点N创建N‘,然后把这些创建出来的节点用next链接起来, 同时我们把<N, N‘>配对信息保存到一个哈希表中;
第二,设置每个节点的random。如果原始链表节点N的random为S, 那么在复制链表中N‘的random应该指向S‘. 第一步中,我们保存了<N, N‘>, <S, S‘>.
 
 1 /*
 2 struct RandomListNode 
 3     int label;
 4     struct RandomListNode *next, *random;
 5     RandomListNode(int x) :
 6             label(x), next(NULL), random(NULL) 
 7     
 8 ;
 9 */
10 class Solution 
11 public:
12     RandomListNode* Clone(RandomListNode* pHead)
13     
14         RandomListNode *res = new RandomListNode(0), *tmp = res, *pNode = pHead; //res是一个没有用的头结点。
15         map<RandomListNode*, RandomListNode*> mp;
16         while (pNode != NULL) 
17             RandomListNode *node = new RandomListNode(pNode->label); //创建新节点N‘(node)
18             tmp->next = node;
19             tmp = node;
20             mp[pNode] = node; //建立哈希映射<N, N‘>
21             pNode = pNode->next;
22         
23         tmp = pHead;
24         for (map<RandomListNode*, RandomListNode*>::iterator it = mp.begin(); it != mp.end(); it++) 
25             //it->second: N‘, it->first: N, if->first->random: S, mp[S] = S‘
26             it->second->random = mp[it->first->random]; 
27         
28         return res->next;
29     
30 ;

 以空间换时间, O(n)的空间复杂度,O(n)的时间复杂度

解法三:

技术图片

 1 /*
 2 struct RandomListNode 
 3     int label;
 4     struct RandomListNode *next, *random;
 5     RandomListNode(int x) :
 6             label(x), next(NULL), random(NULL) 
 7     
 8 ;
 9 */
10 class Solution 
11 public:
12     RandomListNode* Clone(RandomListNode* pHead)
13     
14         if (pHead == NULL)
15             return NULL;
16         RandomListNode *pCurrent = pHead, *copyCurrent = NULL;
17         //复制一遍链表
18         while (pCurrent != NULL) 
19             RandomListNode* node = new RandomListNode(pCurrent->label);
20             node->next = pCurrent->next;
21             pCurrent->next = node;
22             pCurrent = node->next;
23         
24         
25         pCurrent = pHead;
26         while (pCurrent != NULL) 
27             copyCurrent = pCurrent->next;
28             if (pCurrent->random != NULL)
29                 copyCurrent->random = pCurrent->random->next;
30             pCurrent = copyCurrent->next;
31         
32         RandomListNode* pNode = pHead;
33         RandomListNode* pClonedHead = pNode->next;
34         RandomListNode* pClonedNode = pNode->next;
35 
36         pNode->next = pClonedNode->next;
37         pNode = pClonedNode->next;
38         while (pNode != NULL) 
39             pClonedNode->next = pNode->next;
40             pClonedNode = pNode->next;
41             pNode->next = pClonedNode->next;
42             pNode = pClonedNode->next;
43         
44         return pClonedHead;
45     
46 ;

 

以上是关于剑指offer 复杂链表的复制的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 剑指 Offer 35. 复杂链表的复制

剑指offer---复杂链表的复制

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制