难度:中等
题目:
给你一个长度为
n
的链表,每个节点包含一个额外增加的随机指针random
,该指针可以指向链表中的任何节点或空节点。
描述:
构造这个链表的 深拷贝。 深拷贝应该正好由
n
个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next
指针和random
指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
举例:
例如,如果原链表中有
X
和Y
两个节点,其中X.random --> Y
。那么在复制链表中对应的两个节点x
和y
,同样有x.random --> y
。返回复制链表的头节点。
用一个由
n
个节点组成的链表来表示输入/输出中的链表。每个节点用一个[val, random_index]
表示:
val
:一个表示Node.val
的整数。random_index
:随机指针指向的节点索引(范围从0
到n-1
);如果不指向任何节点,则为null
。你的代码 只 接受原链表的头节点
head
作为传入参数。
示例一:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例二:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例三:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
提示:
0 <= n <= 1000
-104 <= Node.val <= 104
Node.random
为null
或指向链表中的节点。
Related Topics
- 哈希表
- 链表
重点!!!———解题思路
第一步:
我们是要复制带随机指针的链表,而且复制的指针地址也不能一样
那么我们第一步要做的就是复制一个新的指针在原指针后面
这个新指针的val,next,random与原指针一样
整个链表变为:原指针->新指针->原指针->新指针->原指针->新指针~~~~
第二步:
因为我们复制的指针的random与原指针一样,但是我们不想让random与之前一样
例:X.random=Y x.random=y
所以在这一步中我们需要改变整个链表的random指针
第三步:
整个链表的指针调整好后,在这一步中我们需要将这一个链表拆分成为两个链表
一个为原链表,一个为新链表
然后我们返回新链表
源码+讲解:
class Solution {
public Node copyRandomList(Node head) {
if (head==null) return null;
Node p=head,q;
//复制节点
while (p!=null){ //因为p指针一直向后移动 所以当p指针指向空时 结束
q=new Node(p.val); //建立一个新节点,使它的val,next,random和原指针相同
q.next=p.next;
q.random=p.random;
p.next=q; //将原指针和新指针相连
p=q.next; //让原指针移动到下一个原指针的位置上,继续去复制节点
}
//调整random指针
p=head.next; //让p指针指向新链表的头节点
while (p!=null){
p.random=p.random==null ? null:p.random.next; //由于random指针有可能是最后一个节点 而且是空值 所以进行一次random的判断
p=p.next==null ? null:p.next.next; //同理 让新链表节点移动时,p的下一个节点就是原指针,如果原指针都没有,更没有复制的指针了,就不用继续移动了
}
//拆分链表
p=q=head.next; //让q节点来记录一下新链表的头节点 以便返回操作
while (p.next!=null){ //如果原链表的最后一个为空值 那么后续也没有节点了
head.next=head.next.next; //让原链表连接在一起
p.next=p.next.next; //让新链表连接在一起
head=head.next; //原链表指针向后移动
p=p.next; //新链表指针向后移动
}
head.next=null; //复制的链表最后一个指针在调整random指针时已经复制为空,但是原链表拆分之后最后一个节点还是未知 所以我们将它赋值为null
return q; //返回新链表的头节点
}
}
运行结果:
如果您还有什么疑问或解答有问题,可在下方评论,我会及时回复。
系列持续更新中,点个订阅吧