题目
给你一个长度为 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 作为传入参数。
1 | 输入:head = new Node(val, next, random ) |
1 | function Node(val, next, random) { |
题解思路
这题其实就是想复制一个链表结构,给你一个链表的头,因为每个节点都有本身的val
,指向下一个节点的next
和一个随机指针random
,根据next
就能顺着链表的头画出整个链表的结构,找到每个节点的随机指针和它本身的next
指针。本体关键是不仅要复制节点上的值,这个值非常好拿,类似node.val
就能拿到,然后递归或者循环下一次(下一次就是从它的next
节点开始复制),拿到所有的val
组成一个数组,那么关键是还要复制它的指针,注意,是引用类型,必须明确指向原先指针所指向的那个栈地址。那么,我们可以把所有节点先遍历出来,存在具有映射关系的Map数据格式中,下次可以方便的拿到原数据,第一次遍历有两个目的:new
一个新的Node
类,把val
复制过来;深拷贝一份原来的节点到map
中,用于下次拷贝指针地址。第二遍历就是找到原先指针指向的node
,并把复制后的node
的next
指向map中复制的相同node
,怎么判断相同呢?就是通过map
的key
啦。存的时候,就把原先复制前的node
当成key
,就唯一了。
代码实现
1 | /** |
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub IssuesGitHub Discussions