題目描述:
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
解題思路:
本題是對複雜鏈表的複製,這裏實現的方法時間複雜度是O(n),並且沒有開闢額外的空間;
1)首先複製原來的複雜(隨機)鏈表,形成A->A`->B->B`->...->Z->Z`連接形式,其中A`、B`...Z`是new出來的複雜鏈表元素,但是沒有複雜鏈表的random指針,該指針賦值爲nullptr;該步的時間複雜度爲O(n);
2)其次遍歷複製後的鏈表,將A的random指針賦值給A`的random指針,該步驟的時間複雜度爲O(n);
3) 最後將賦值後的鏈表拆開爲 A->B->...->Z 和A`->B`->...->Z`,從而完成複雜(隨機)鏈表的複製,該步驟的時間複雜度也爲O(n)。
綜上該種方法除了new必要的複製鏈表元素之外,沒有開闢額外的空間,總的時間複雜度爲O(n)。
此外還有無腦複製的方法,時間複雜度爲O(n^2);開闢額外空間hash的方法,時間複雜度也爲O(n),但是開闢了一個大小爲O(n)的哈希表。
通過代碼(C++):
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
//整個方法時間複雜度O(n),並且沒有開闢額外空間
RandomListNode* Clone(RandomListNode* pHead)
{
RandomListNode* cloneRandomListNodes = nullptr;
if(pHead == nullptr)
return cloneRandomListNodes;
cloneListNodes(pHead);
copyRandomNodes(pHead);
cloneRandomListNodes = splitLists(pHead);
return cloneRandomListNodes;
}
//第一步複製複雜鏈表建立A->A`->B->B`...->Z->Z`
void cloneListNodes(RandomListNode* pHead)
{
RandomListNode* curNode = pHead;
while(curNode != nullptr)
{
RandomListNode * cloneRandomListNode = new RandomListNode(0);
cloneRandomListNode->label = curNode->label;
cloneRandomListNode->next = curNode->next;
cloneRandomListNode->random = nullptr;
curNode->next = cloneRandomListNode;
curNode = cloneRandomListNode->next;
}
}
//第二步複製原始鏈表的任意指針
void copyRandomNodes(RandomListNode* pHead)
{
RandomListNode* curNode = pHead;
while(curNode != nullptr)
{
if(curNode->random != nullptr)
{
curNode->next->random = curNode->random->next;
}
curNode = curNode->next->next;
}
}
//第三步拆分鏈表爲兩個鏈表
RandomListNode* splitLists(RandomListNode* pHead)
{
RandomListNode * curNode = pHead;
RandomListNode * srcRandomListNodes = pHead;
RandomListNode * cloneRandomListNodes = nullptr;
RandomListNode * curCloneNode = nullptr;
if(pHead != nullptr)
{
cloneRandomListNodes = pHead->next;
curNode = cloneRandomListNodes->next;
curCloneNode = cloneRandomListNodes;
pHead->next = curNode;
}
while(curNode != nullptr)
{
curCloneNode->next = curNode->next;
curCloneNode = curNode->next;
curNode->next = curCloneNode->next;
curNode = curCloneNode->next;
}
return cloneRandomListNodes;
}
};