剑指Offer_面试题26_复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的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;

}
测试结果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章