複雜鏈表的複製(劍指offer 面試題35)

題目描述:

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

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