题目描述
题目分析:
这道题乍一看很复杂,其实不是很难,意思就是让你原封不动地复制一个链表,不过这个链表特殊一点,不仅每个节点有指向下一个节点的指针,还有一个指向了该链表中某个随机节点的指针
解题思路
①拷贝节点插入到新节点的后面
②控制拷贝节点的random
③拷贝节点接下来尾插组成拷贝链表,并且恢复原链表
①拷贝节点插入到新节点的后面
之前单链表那篇博客就已经详细讲解了增删查改相关问题,这里就不赘述了~
②控制拷贝节点的random
这一步要做的事情就是把复制节点的random指向它该指的位置(和对应的原链表的节点一致)
分析一下前两个拷贝节点的ramdom情况~
7这个拷贝节点的ramdom
由于原链表7这个节点的random是指向空的,因此拷贝节点的random也指向空即可
13这个拷贝节点的ramdom
由于原链表13这个节点的ramdom是指向7这个节点,因此13这个拷贝节点的ramdom也应该指向拷贝节点7,那怎么找自己的拷贝节点7呢?别忘了,在第一步中,我们已经将每个拷贝节点插入到了原链表节点的后面,假设指向当前节点的指针是cur,因此只需要 copy->random = cur->random->next(核心代码) 这句代码就可以实现,再让cur = copy->next就可以往后遍历了~
③拷贝节点解下来尾插组成拷贝链表,并且恢复原链表
解下来第1个拷贝节点,恢复第1个和第2个节点之间的链接
解下来第2个拷贝节点,尾插到第1个节点后面,恢复第2个和第3个节点之间的链接
后面的过程依次类推~~
完整代码
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;
struct Node* next = cur->next;
cur->next = copy;
copy->next = next;
cur = next;
}
//2.控制拷贝节点的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)
{
copyTail = copyHead = copy;
}
else
{
copyTail->next = copy;
copyTail = copyTail->next;
}
cur->next= next;
cur = next;
}
return copyHead;
}
本篇博客就分享到这啦,欢迎大家交流指正~