オリジナルのタイトルリンクの
アイデア:
- この質問は直感的にアルゴリズムさえ必要としません。一般的なコピーのアイデアに従い、新しいスペースを開いてから、対応するノードの値をコピーします。最初にランダムに見る必要はありません。
- 厄介なのは、ノード->ランダムがランダムにポイントすることであり、従うべきルールはありません。
- そこで、ヘッドノードに対する各ノードのランダムのオフセットを見つけ、新しいリンクリストの対応するオフセットでランダムノードを見つけて、それを指すことを考えました。
- 最初はタイムアウトになると思っていましたが、54%の時間と60%のメモリという良好な結果が得られました。
- 悪い点は、位置を示すために多くのポインタが使用されていることです。これは少し面倒です。簡単なアイデアは、代金を支払うことです。
コードを与える:
/*
// 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 NULL;
Node* current = NULL;
current = head;
Node *result = NULL;
Node *newHead = NULL;
result = new Node(head->val);
newHead = result;
while(current != NULL){
Node* midNode = new Node(-1);
if(current->next != NULL){
result->next = midNode;
}
result->val = current->val;
current = current->next;
result = result->next;
}
current = head;
result = newHead;
Node *subRandom;
Node *oldCurrent;
oldCurrent = head;
subRandom = newHead;
while(current != NULL){
if(current->random == NULL){
subRandom->random = NULL;
}else{
int i = 0;
Node *subCurrent;
subCurrent = current->random;
while(oldCurrent != subCurrent){
//在这里找当前节点的random的偏移量
i++;
oldCurrent = oldCurrent->next;
}
while(i>0){
//去找新链表中的对应偏移量下的节点
result = result->next;
i--;
}
subRandom->random = result;
}
subRandom = subRandom->next;
result = newHead;
current = current->next;
oldCurrent = head;
}
return newHead;
}
};
≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈ ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈ ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈1
。コメントの問題解決方法を見てください。より高度なのは、unordered_map
を使用して多くのトラバーサルオーバーヘッド
2.もちろん、オファーブックに
は方法があります。この方法の説明は次のとおりです。
- 元のリンクリストの各ノードの背後にあるノードと同じノードをコピーすると、元のリンクリスト構造が破棄されます。隣接する繰り返し要素を示します。最初の要素は古い要素で、後者は新しい要素です。
- 新しく形成された長いリンクリストで、元のリンクリストのランダムな関係を使用して、新しい各ノードのランダム性を設定します。
- 元のリンクリストを復元し、長いリンクリストからすべての新しいノードを切り取って、正常にコピーされたリンクリストを形成します。
この種の考え方は本当に学ぶ価値があります!!!