題目來源於 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,隨機指標指向它自己。
複製程式碼
題目解析
-
在原連結串列的每個節點後面拷貝出一個新的節點
-
依次給新的節點的隨機指標賦值,而且這個賦值非常容易 cur->next->random = cur->random->next
-
斷開連結串列可得到深度拷貝後的新連結串列
之所以說這個方法比較巧妙是因為相較於一般的解法(如使用 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
個人公眾號:五分鐘學演算法