題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的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;
}
測試結果: