コンテンツ
1.トピックの説明
トピックリンク:ランダムなポインタを使用してリンクリストをコピーします
質問:長さnのリンクリストを提供します。各ノードには、リンクリスト内の任意のノードまたは空のノードを指すことができる追加のランダムポインターランダムが含まれています。このリンクリストのディープコピーを作成します。ディープコピーは、正確にn個の新しいノードで構成する必要があります。ここで、各新しいノードの値は、対応する元のノードの値に設定されます。新しいノードの次のポインターとランダムポインターも、コピーされたリンクリストの新しいノードを指す必要があります。これにより、元のリンクリストとコピーされたリンクリストのこれらのポインターは、同じリンクリストの状態を表すことができます。コピーされたリンクリスト内のどのポインタも、元のリンクリスト内のノードを指してはなりません。たとえば、元のリンクリストに2つのノードXとYがある場合、X.random->Yです。次に、レプリケーションリンクリストの対応する2つのノードxとyにもx.random->yがあります。
複製されたリンクリストのヘッドノードを返します。
例:
自分で例を見てみましょう。
2.方法1の分析と参照コード
リンクリストの概念を使用してそれを行い、特定の方法は3つのステップに分かれています。
1.リンクリストノードをリンクにコピーします。リンクをコピーすると、次のようになります。
2.コピーする新しいノードにランダムポインタフィールドを割り当てます。割り当ての長さは次のとおりです。
3.次のように、コピーした新しいリンクリストを元のリンクリストから切断します。
参照コード:
class Solution {
public Node copyRandomList(Node head) {
//判空操作,如果链表为空直接返回
if(head == null){
return head;
}
//复制链接
Node cur = head;
while(cur != null){
Node newNode = new Node(cur.val);//以原链表的值new新节点
newNode.next = cur.next;
cur.next = newNode;
cur = newNode.next;
}
//给复制的节点赋随机值
cur = head;
Node newNode = cur.next;
while(cur != null){
if(cur.random != null){
newNode.random = cur.random.next;
}
cur = newNode.next;
if(cur != null){
newNode = cur.next;
}
}
//将复制的链表从原链表当中断开
cur = head;
Node newHead = cur.next;//新链表头节点
Node newCur = newHead;//新链表节点的引用
while(cur != null){
cur.next = newCur.next;
cur = newCur.next;
if(cur != null){
newCur.next = cur.next;
newCur = cur.next;
}
}
return newHead;
}
}
3.方法2の分析と参照コード
ハッシュマップのデータ構造を使用して実行します。具体的な方法は、次の3つのステップに分かれています。
1.元のリンクリストをトラバースし、元のリンクリストのノードをKとして設定し、新しくコピーされたノードをVとして設定し、Kと対応するVをハッシュマップに格納します。その後は次のようになります。
2.ハッシュマップ内のVのノードを順番にリンクします。リンクは次のとおりです。
3.ハッシュマップのVのノードにランダムなポインタフィールドを順番に割り当てます。完了すると、次のようになります。
参照コード:
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> m = new HashMap<>();
Node cur = head;
//hashmap中存放的K-V为:原链表的节点-新复制的节点
while(cur != null){
m.put(cur,new Node(cur.val));
cur = cur.next;
}
cur = head;
while(cur != null){
m.get(cur).next = m.get(cur.next);//将V中的节点链接起来
m.get(cur).random = m.get(cur.random);//给V中的节点赋随机指针域
cur = cur.next;
}
return m.get(head);
}
}