劍指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;

}
測試結果:



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