ランダムなポインタでリンクリストをコピーする
問題の説明
リンクリストを指定すると、各ノードには追加のランダムポインターが含まれ、リンクリスト内の任意のノードまたは空のノードを指すことができます。
このリンクリストのディープコピーを返すように要求します。
n個のノードで構成されるリンクリストを使用して、入力/出力のリンクリストを表します。各ノードは[val、random_index]で表されます。
val:Node.valを表す整数。
random_index:ランダムポインタが指すノードのインデックス(0からn-1の範囲)。どのノードも指していない場合はnullです。
[注]ディープコピー:ディープコピーとは、ソースオブジェクトとコピーされたオブジェクトが互いに独立しており、いずれかを変更しても他のオブジェクトに影響を与えないことを意味します。
問題解決のアイデア
考えずに別の日...
最後に、それは問題解決領域のアイデアに従って書かれています:
アイデアは3つのステップに分かれています。
①新しいノードを各古いノードの後ろに接続します;
②新しいノードのランダムは古いノードの次のランダムを指します;
③新しいノードと古いノードは2つのリンクリストに分けられます。
たとえば、例のステップ1:
コードの実装:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(!head)
return head;
Node* cur = head;
while(cur){
//将新结点加到原链表结点的后面
Node* temp = new Node(cur->val);
Node* q = cur->next;
cur->next = temp;
temp->next = q;
cur = q;
}
cur = head;
Node* new_cur = cur->next;
while(cur){
//将新结点的随机指针加上
if(!cur->random)
new_cur->random = NULL;
else
new_cur->random = cur->random->next;
cur = new_cur->next;
if(!cur) break;
new_cur = cur->next;
}
Node* new_head = head->next;
cur = head;
new_cur = new_head;
while(cur && cur->next){
//分离head和new_head
cur->next = new_cur->next;
cur =cur->next;
if(!cur) break;
new_cur->next = cur->next;
new_cur = new_cur->next;
}
return new_head;
}
};