@TOC
1. 题目
题目链接:复制带随机指针的链表
2. 思路
这道题目的难点在于 :random
指针也都应指向复制链表中的新节点
这思路也太妙了吧!
:star: 1. 复制节点,插入在原节点和下一个节点之间
:star: 2. 根据原节点的random
,处理复制节点的random
:star: 3. 把复制节点解下来,链接成一个新链表,恢复原链表的链接关系。
3. 题解
struct Node* copyRandomList(struct Node* head) {
if(head == NULL)
return NULL;
// 1.复制节点,插入到原节点和下一个节点之间
struct Node* cur = head;
while(cur)
{
struct Node* copynode = (struct Node*)malloc(sizeof(struct Node));
copynode->val = cur->val;
struct Node* next = cur->next;
//链接
cur->next = copynode;
copynode->next = next;
cur = next;
}
// 2. 根据源节点的random处理复制节点的random
cur = head;
while(cur)
{
if(cur->random == NULL)
{
cur->next->random = NULL;
}
else
{
cur->next->random = cur->random->next;
}
cur = cur->next->next;
}
// 3.复制节点解下来缝合成新链表,缝合原链表链接关系
cur = head;
struct Node* copyhead = head->next;
while(cur)
{
struct Node* copynode = cur->next;
struct Node* next = copynode->next;
cur->next = next; //缝合
//链接
if(next == NULL)
copynode->next = NULL;
else
copynode->next = next->next;
// 迭代
cur = next;
}
return copyhead;
}
这是另一份参考代码,差别主要是在第三部分,它采取尾插构建新链表,我直接在2的结构上缝合。
struct Node* copyRandomList(struct Node* head) {
struct Node* cur = head;
//1.拷贝节点,插入到原节点的后面
while(cur)
{
struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
copy->val = cur->val;
//插入copy节点
copy->next = cur->next;
cur->next = copy;
//迭代着向后走
cur = copy->next;
}
//2.根据原节点,处理copy节点的random
cur = head;
while(cur)
{
struct Node* copy = cur->next;
if(cur->random == NULL)
{
copy->random = NULL;
}
else
{
copy->random = cur->random->next;
}
cur = copy->next;
}
//3.把拷贝节点解下来,链接成新链表(尾插链接),同时恢复原链表
struct Node *copyHead = NULL,*copyTail = NULL;//不需要每次都找尾
cur = head;
while(cur)
{
struct Node* copy = cur->next;
struct Node* next = copy->next;
if(copyTail == NULL)
{
//第一个
copyHead = copyTail = copy;
}
else
{
//尾插
copyTail->next = copy;
copyTail = copy;//这样的话更新
}
//恢复原链表
cur->next = next;
cur = next;
}
return copyHead;
}