「複製帶隨機指標的連結串列」的一個很巧妙解法

程式設計師吳師兄發表於2019-04-18

題目來源於 LeetCode 上第 138 號問題:複製帶隨機指標的連結串列。題目難度為 Medium,目前通過率為 40.5% 。

題目描述

給定一個連結串列,每個節點包含一個額外增加的隨機指標,該指標可以指向連結串列中的任何節點或空節點。

要求返回這個連結串列的深拷貝

示例:

「複製帶隨機指標的連結串列」的一個很巧妙解法

輸入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解釋:
節點 1 的值是 1,它的下一個指標和隨機指標都指向節點 2 。
節點 2 的值是 2,它的下一個指標指向 null,隨機指標指向它自己。
複製程式碼

題目解析

  1. 在原連結串列的每個節點後面拷貝出一個新的節點

  2. 依次給新的節點的隨機指標賦值,而且這個賦值非常容易 cur->next->random = cur->random->next

  3. 斷開連結串列可得到深度拷貝後的新連結串列

之所以說這個方法比較巧妙是因為相較於一般的解法(如使用 Hash map )來處理,上面這個解法 不需要佔用額外的空間

動畫描述

動畫描述

程式碼實現

我發現帶指標的題目使用 C++ 版本更容易描述,所以下面的程式碼實現是 C++ 版本。

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if (!head) return NULL;
        RandomListNode *cur = head;
        while (cur) {
            RandomListNode *node = new RandomListNode(cur->label);
            node->next = cur->next;
            cur->next = node;
            cur = node->next;
        }
        cur = head;
        while (cur) {
            if (cur->random) {
                cur->next->random = cur->random->next;
            }
            cur = cur->next->next;
        }
        cur = head;
        RandomListNode *res = head->next;
        while (cur) {
            RandomListNode *tmp = cur->next;
            cur->next = tmp->next;
            if(tmp->next) tmp->next = tmp->next->next;
            cur = cur->next;
        }
        return res;
    }
};
複製程式碼

個人網站:www.cxyxiaowu.com

個人公眾號:五分鐘學演算法

相關文章