剑指Offer第25题:复杂链表的复制

题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

解题思路:
1、在原始链表的每个元素后面都插入一个对应元素值的新结点;
2、根据原始结点的随机指针,复制新节点的随机指针;
3、断开原始链表与复制好的新链表。
注意:对链表取值,取next操作时,一定要先确定该位置为空

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
RandomListNode* Clone(RandomListNode* pHead) {
if (!pHead) return NULL; // 注意先判断原始链表是否为空
RandomListNode* p = pHead;
while (p) {
RandomListNode* tmp = p->next;
p->next = new RandomListNode(p->label);
p->next->next = tmp;
p = p->next->next;
}
p = pHead;
while (p) {
if (p->random) p->next->random = p->random->next; // 注意判断p->random是否为空,再来取next
else p->next->random = NULL;
p = p->next->next; // 因为先前复制过一遍链表,所以链表的结点数为偶数,因此可以不用判断p->next是否为空
}
p = pHead;
RandomListNode* res = p->next;
RandomListNode* p2 = res;
while (p2) {
p->next = p2->next; // while (p2), 所以p2一定非空
p = p->next;
if (p) p2->next = p->next; // 先判断p是否为空,再取next
else p2->next = NULL;
p2 = p2->next;
}
return res;
}