题目描述:
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
深拷贝:深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一 个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。(来自百度百科)
所以说,拷贝完不会对原链表产生任何影响。
那么???这道题的解题思路是什么呢?先看下图
方框代表老结点,菱形代表新结点,分3步:
1、复制老链表,此时复制的是不带随机结点random,并将新结点插入到老结点的 后边。
2、复制随机结点random
3、将链表拆分成老链表和新链表
进行完第2步,链表就如下图:
这道题的难点在于随机结点的复制,但是我们可以看到newNode->random就为oldNode->random->next
理解了这一点,这道题就容易啦,下面贴出详细代码:
Node* copyRandomList(Node* head) {
//分3步
//1、将旧链表复制一份,不含随机指针的,将新结点插入到老结点的后面
//2、根据老结点的random复制新结点的random
//3、链表拆分
if(head==NULL)
{
return NULL;
}
Node* oldNode=head;
while(oldNode!=NULL)
{
Node* newNode=(Node*)malloc(sizeof(Node));
newNode->val=oldNode->val;
Node* oldNext=oldNode->next;
newNode->next=oldNext;//
oldNode->next=newNode;//
oldNode=oldNext;
}
oldNode=head;//又让遍历的指针从头开始,只遍历老结点
while(oldNode!=NULL)
{
Node* newNode=oldNode->next;
if(oldNode->random==NULL)
{
newNode->random=NULL;
}
else
{
newNode->random=oldNode->random->next;
}
oldNode=newNode->next;
}
oldNode=head;
Node* newHead=head->next;
while(oldNode!=NULL)
{
Node* newNode=oldNode->next;
oldNode->next=newNode->next;
if(newNode->next!=NULL)
{
newNode->next=newNode->next->next;
}
oldNode=oldNode->next;
}
return newHead;
}