题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的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 };
来源:https://www.cnblogs.com/qinduanyinghua/p/11365542.html