题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路一
1.创建一个map 遍历链表将每个结点 和复制当前结点的结点 构成一个key 和value放进map中
2.再次遍历链表 将每个结点作为key去查找map中的val 即复制的结点 它的next域就是 当前结点
的next在map中的val 他的random域就是 当前结点的random在map中的val
这种方法的时间复杂度为0(n) 额外空间复杂度为O(n)
下面介绍一种时间复杂度为0(n) 额外空间复杂度为O(1)的方法
思路二
利用和思路一同样的思想 只需要将复制的节点放在当前的结点的后面 则复制结点的random域就是当前节点的random域下一个结点 最后重新拆分链表就是了
**请看代码结合注释理解 拆分链表部分好好看看 **
实现起来其实还是不是很简单的。
下面是java代码实现
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead == null) {
return null;
}
RandomListNode node = pHead;
// 遍历链表将复制结点放在当前结点的后面
while(node != null) {
RandomListNode newNode = new RandomListNode(node.label);
newNode.next = node.next;
node.next = newNode;
node = newNode.next;
}
node = pHead;
// 遍历链表 将复制结点的random指向当前结点的random的next
while(node != null && node.next != null) {
if(node.random != null) {
node.next.random = node.random.next;
}
node = node.next.next;
}
RandomListNode res = pHead.next;
node = pHead;
RandomListNode node1 = res;
// 拆分链表
while(node != null && node.next != null) {
node.next = node.next.next;
node1.next = node.next == null ? null : node.next.next;
node1 = node1.next;
node = node.next;
}
return res;
}
}