
 难度 中等 题目链接
 示例:
 
 解题思路:
 首先,大家肯定会这样想:定义一个cur循环遍历,每次遍历一个,就malloc一个。
 
 当遍历后面的时候,就开始尾插。
 
 但现在有一个问题是:这个random指针该这么拷贝呢?因为我们不知道我们拷贝的random该去指向那个结点的地址。有的同学会说找val值,这是不行的。因为可能会有相同的值,你不知道该指向哪一个。
解决方法:
 1. 拷贝结点连接在原结点后面。
 
 2. 连接拷贝结点的random,拷贝结点的random在原结点random指向结点的next。
 那么第一个7的random很简单是NULL,我们直接指向NULL就行了,无需去找。
 
 第二个13的random是原结点13的random指向的结点7的next
 
 后面的结点的random也是按照这样的方式来找,然后连接起来。
3. 把拷贝结点解下来,连接到一起。
代码实现步骤:
 
 我们用一个cur来遍历,然后把拷贝结点的叫做copy。
 
 现在我们要把拷贝结点连接在原结点的后面,但我们不能这样去连接:
 
 因为这样去连接,我们就找不到13结点的地址了。所以我们只能这样去连接。
 
 
 下一步就是找下一个结点,可以是cur的next的next或者是copy的next
 
 
 那么后面的结点也是按照这样的方式来。拷贝结点完成了之后,我们就需要找到拷贝结点的random。
 
 我们这里还是用cur和copy来遍历。如果原结点的random指向的是NULL,我们拷贝结点的random直接指向NULL。
 
 如果原结点random不指向NULL,那么拷贝结点的random就为原结点的random的next
 
 然后我们在找下一个原结点。
 
 这样第二步也完成了,所以拷贝结点的random都连接好了。现在我们要开始第三步,把所有的拷贝结点解下来,然后连接在一起。连接在一起也就是尾插。
 
 我们这里使用三个指针cur,copy,next,这样的话会好控制一点。
 
 因为是尾插,我们可以先定义一个copyHead和copyTail,把这两个先置为NULL。如果为NULL,就直接赋值。如果不为空,就将copy尾插。
 
 我们尾插之前也可以把原链表还原一下。还原的话就是把cur->next=next
 
 此时,拷贝结点就是这个样子了:
 
 那么我们就需要更新cur,让它找到下一个原结点。下一个原结点的地址就是next,直接赋值给cur就行了。copy和next也继续更新。
 
 
 此时我们就需要尾插了。我们把copy结点插在copyTail的next上,然后更新一下copyTail。
 
 
 最后return拷贝链表的头指针copyHead。
完整代码如下:
 



















