LeetCode 138. 复制带随机指针的链表

在这里插入图片描述
难度 中等 题目链接

1. 方法一

示例:
在这里插入图片描述
解题思路:
首先,大家肯定会这样想:定义一个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。

完整代码如下:
在这里插入图片描述

2. 方法二

用map来记录老结点和新结点。
在这里插入图片描述
遍历一遍老链表,在map的value中拷贝新结点:
在这里插入图片描述
再遍历一遍老链表,在map中找到新结点(value),它的next就是map中老结点的next。它的random就是map中老结点的random。
在这里插入图片描述
完整代码:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值