中難易度478
リンクリストを指定すると、各ノードには追加のランダムポインターが含まれ、リンクリスト内の任意のノードまたは空のノードを指すことができます。
このリンクリストのディープコピーを返すように要求します 。
n
ノードのリンクリストを使用して 、入力/出力のリンクリストを表します。各ノードは1つで[val, random_index]
表されます :
val
:表されるNode.val
整数。random_index
:ノードのインデックスがランダムポインタ(範囲によって指さ0
にn-1
)、それは、任意のノードを指していない場合、それがありますnull
。
例1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]] 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
例2:
输入:head = [[1,1],[2,1]] 输出:[[1,1],[2,1]]
例3:
输入:head = [[3,null],[3,0],[3,null]] 输出:[[3,null],[3,0],[3,null]]
例4:
输入:head = [] 输出:[] 解释:给定的链表为空(空指针),因此返回 null。
促す:
-10000 <= Node.val <= 10000
Node.random
空(null)であるか、リンクリスト内のノードを指しています。- ノードの数は1000を超えません。
ディープコピーの意味
簡単に言うと、元のノードと同じ構造と値でデータ構造を構築しますが、その中のノードは元のノードへの参照ではありません。
この兄貴の解決策を賞賛する必要があります!!この質問が私に与えた悟りも記録しなければなりません!
/*
// 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 == NULL){
return head;
}
unordered_map<Node*, Node*> ump;
Node* cur = head;
while(cur != NULL){
Node* copy = new Node(cur->val);
ump[cur] = copy;
cur = cur->next;
}
cur = head;
while(cur != NULL){
ump[cur]->next = ump[cur->next];
ump[cur]->random = ump[cur->random];
cur = cur->next;
}
return ump[head];
}
};
まず、マップを使用してリンクリストを格納します。キーは古いリンクリストノードであり、値は新しいノードです。したがって、ここでの値は、ディープコピーを処理するリンクリストです。もう1つの利点は、リンクリストインデックスをポインタとして使用してリンクリストを操作できることです。マップの操作中に、リンクリストの取得を同期できます。少し複雑に見えますが、実際には非常に理解しやすく、多くのスペースを節約します。
次に、リンクリストをトラバースした後、元のリンクリストノードに基づいてキーが生成され、ノード値が新しく宣言されたノードの値として対応する値に渡されます。これは単なるレイヤーコピーであり、次はありません。とランダム。コピー。したがって、リンクリストの2回目のトラバーサルでは、マップ内のキーと値が使用されます。これは、次のランダムな描画を完了するためのすばらしいコードで次のように実装されます。ump [cur]は、それがすべて新しく、valのみであることを意味します。しかし、この操作の後、次とランダムは完璧です!!本当にすごい!
ump [cur]-> next = ump [cur-> next];
ump [cur]-> random = ump [cur-> random];