题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
分析:一般来说是分两步,首先复制原始链表上的每一个结点,并用next链起来,第二步设置每个结点的random指针。但直接这样做时间复杂度很高,达到O(n^2)级别。
有两种解决方法。
方法一:空间换时间,复制结点的同时构建哈希表或者映射map,先执行第一步,再根据hash便设置random指针,这种方式空间复杂度o(n),时间复杂度o(n).
方法二:时间复杂度o(n),无辅助空间。步骤是①每复制一个结点就把它链到源结点后面②设置random指针,源结点指向哪个结点,复制结点指向哪个结点的后继;③分拆两个链表
代码:
#include <stdio.h>
#include <stdlib.h>
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
//[1]复制结点,插入到原结点后方
void nodeClone(RandomListNode *head)
{
RandomListNode *pNode = head;
while (pNode != NULL)
{
RandomListNode *pClone = new RandomListNode(pNode->label);
pClone->next = pNode->next;
pNode->next = pClone;
pNode = pClone->next;
}
}
//[2]还原新结点的random指针
void connectRandom(RandomListNode *head)
{
RandomListNode *pNode = head;
while (pNode != NULL)
{
RandomListNode *pClone = pNode->next;
if (pNode->random)
{
pClone->random = pNode->random->next;
}
pNode = pClone->next;
}
}
//[3]拆分
RandomListNode *reconnect(RandomListNode *head)
{
RandomListNode *pNode = head;
RandomListNode *result = head->next;
while (pNode != NULL)
{
RandomListNode *pClone = pNode->next;
pNode->next = pClone->next;
pNode = pNode->next;
if (pNode != NULL)
pClone->next = pNode->next;
}
return result;
}
RandomListNode* Clone(RandomListNode* pHead)
{
if (!pHead) return NULL;
nodeClone(pHead);
connectRandom(pHead);
return reconnect(pHead);
}
//打印结点,只打印顺序指针
void printList(RandomListNode *head)
{
while (head)
{
printf("%d ", head->label);
head = head->next;
}
printf("\n");
}
//测试
int main()
{
//建表
RandomListNode *head = new RandomListNode(1);
RandomListNode *node2 = new RandomListNode(2);
RandomListNode *node3 = new RandomListNode(3);
RandomListNode *node4 = new RandomListNode(4);
RandomListNode *node5 = new RandomListNode(5);
head->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
head->random = node3;
node2->random = node5;
node4->random = node2;
printList(head);
//测试
RandomListNode *newHead = Clone(head);
printList(newHead);
getchar();
return 0;
}
测试结果: