1.長さnのリンクリストを提供します。各ノードには、リンクリスト内の任意のノードまたは空のノードを指すことができる追加のランダムポインタランダムが含まれています。
このリンクリストのディープコピーを作成します。ディープコピーは、正確に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。
コードは、元のリンクリストのヘッドノードのみを着信パラメーターとして受け入れます。テストの質問のソース:LeetCode
コードとその説明は次のとおりです。
1.この問題を解決する方法はたくさんあります。ここでは、新しいリンクリストをリンクして一緒にトラバースする方法を使用します:(合計3つのプロセスがあります)以下に示すように:
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
typedef struct Node node;
struct Node* copyRandomList(struct Node* head) {
if (NULL == head) {
return NULL;
}
node* cur = head;
while (cur != NULL) {//这个循环用来创建新结点并连接原链表
node* new_node = (node*)malloc(sizeof(node));
new_node->val = cur->val;
new_node->next = cur->next;
cur->next = new_node;
cur = new_node->next;
}
node* temp = head;
node* head2 = head->next;
while (1) {//该循环在遍历原链表的同时跟随原链表一起遍历新链表,找到每一个的
//随机指针random的位置进行相应存储
//总共遍历所有元素
node* cur1 = head;
node* cur2 = head->next;
while (cur1 != temp->random) {//每个元素的random都要在整段链表中遍历,
//来寻找对应的地址.
cur1 = cur1->next->next;
if (NULL == cur1) {
cur2 = cur2->next;
break;
}
cur2 = cur2->next->next;
}
head2->random = cur2;
temp = temp->next->next;
if (NULL == temp) {
break;
}
head2 = head2->next->next;
}
node* node_1 = head;
node* node_2 = head->next;
node* new_head_node = head->next;
while (node_2->next != NULL) {//遍历完之后新的链表的每个结点的random都指向了
//相应的地方,这时断开链表.
node_1->next = node_2->next;
node_2->next = node_1->next->next;
node_1 = node_1->next;
node_2 = node_2->next;
}
node_1->next = NULL;
return new_head_node;//返回新链表的首节点地址
}