LeetCode //C - 138. ランダム ポインタを使用したリストのコピー

138. ランダムポインタによるリストのコピー

長さ n のリンク リストは、各ノードに追加のランダム ポインタが含まれるように指定されます。このポインタは、リスト内の任意のノードまたは null を指すことができます。

リストのディープコピーを作成します。ディープ コピーは正確に n 個の新しいノードで構成されている必要があります。各新しいノードの値は、対応する元のノードの値に設定されます。新しいノードの次のポインタとランダムなポインタは両方とも、元のリストとコピーされたリスト内のポインタが同じリスト状態を表すように、コピーされたリスト内の新しいノードを指す必要があります。新しいリスト内のポインタはいずれも、元のリスト内のノードを指してはなりません。

たとえば、元のリストに 2 つのノード X と Y があり、X.random --> Y である場合、コピーされたリスト内の対応する 2 つのノード x および y については、x.random --> y となります。

コピーしたリンクリストの先頭を返します。

リンク リストは、入出力では n 個のノードのリストとして表されます。各ノードは [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]]

制約:

  • 0 <= n <= 1000
  • − 1 0 4 < = ノード。val < = 1 0 4 -10^4 <= Node.val <= 10^41 04<=ノード_ _ _ v a l<=1 04
  • Node.random が null であるか、リンクされたリスト内のノードを指しています。

From: LeetCode
Link: 138. ランダム ポインタを使用したリストのコピー


解決:

アイデア:

この問題の主な課題は、ノード間のランダムなポインタ関係を維持しながら、リンク リストのディープ コピーを作成することです。このソリューションでは、元のノードとそのコピーの間のマッピングを使用して、コピーされたリスト内の次のランダムなポインターが適切なノードを指すようにします。

手順:
1. ノードを数えます。

  • ノードをコピーする前に、元のリストを調べてノードの数を数えます。このカウントは、マッピング構造にメモリを割り当てるのに役立ちます。

2. マッピング構造を初期化します。

  • oldNodes と newNodes の 2 つの配列を使用します。
  • oldNodes は元のノードへのポインタを保存します。
  • newNodes は、対応するコピーされたノードへのポインターを格納します。
  • 2 つの配列間の関係は、oldNodes 内の元のノードのインデックスが newNodes 内のコピーのインデックスと一致するということです。

3. ノードをコピーし、マッピング構造を塗りつぶします。

  • 元のリストを再度調べて、ノードごとにそのコピーを作成します。
  • 元のノードを oldNodes 配列に追加し、そのコピーを newNodes 配列に追加して、それらが同じインデックスにあることを確認します。

4. 次のランダムなポインターを確立します。

  • 元のリストをもう一度調べます。
  • コピーされたノードの次のポインターの場合:
    • oldNodes 配列内で元のノードの次のポインターのインデックスを見つけます。
    • 次に、このインデックスを使用して、コピーされたノードの次のポインターが newNodes 配列内の適切なノードを指すように設定します。
  • 同様に、ランダム ポインタの場合は次のようになります。
    • oldNodes 配列内で元のノードのランダム ポインターのインデックスを見つけます。
    • 次に、このインデックスを使用して、コピーされたノードのランダム ポインタが newNodes 配列内の適切なノードを指すように設定します。
コード:
/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) {
    
    
    if (head == NULL) return NULL;

    struct Node* curr = head;
    int count = 0;

    // Count nodes
    while (curr) {
    
    
        count++;
        curr = curr->next;
    }

    struct Node* oldNodes[count];
    struct Node* newNodes[count];

    curr = head;
    int index = 0;

    // 1. Copy nodes and fill our mapping structure
    while (curr) {
    
    
        struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
        newNode->val = curr->val;
        newNode->next = NULL;
        newNode->random = NULL;

        oldNodes[index] = curr;
        newNodes[index] = newNode;

        curr = curr->next;
        index++;
    }

    curr = head;
    index = 0;

    // 2. Copy next and random pointers using our mapping structure
    while (curr) {
    
    
        if (curr->next) {
    
    
            int nextIndex = 0;
            while (oldNodes[nextIndex] != curr->next) {
    
    
                nextIndex++;
            }
            newNodes[index]->next = newNodes[nextIndex];
        }
        
        if (curr->random) {
    
    
            int randomIndex = 0;
            while (oldNodes[randomIndex] != curr->random) {
    
    
                randomIndex++;
            }
            newNodes[index]->random = newNodes[randomIndex];
        }

        curr = curr->next;
        index++;
    }

    return newNodes[0];
}

おすすめ

転載: blog.csdn.net/navicheung/article/details/132487305