题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
参考https://www.nowcoder.com/profile/1687题解
完全不懂深复制的含义--将所有的节点以及节点之间的指针复制一遍
重复下两种方法的思路
方法一:
1.复制下所有的节点,并将映射关系用hashmap存储
2.遍历原链表,将指针关系添加到映射的新节点上
3.返回新链表--代码如注释部分
方法二:
1.先遍历,复制所有节点,插入到原节点右侧
2.再遍历,将所有的指针关系添加到新节点上
2.最后遍历实现新旧链表的分离(分离之后原来的链表也得是一个链表)
具体见下图
java代码
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
import java.util.*;
public class Solution {
// public RandomListNode Clone(RandomListNode pHead)
// {
// //使用hashMap来存放随意指针的对应关系
// HashMap<RandomListNode,RandomListNode> map=new HashMap<>();
// RandomListNode p=pHead;
// //先将所有节点复制一遍,并保存映射关系
// while( p != null){
// RandomListNode node=new RandomListNode(p.label);
// map.put(p,node);
// p=p.next;
// }
// //再遍历一遍,处理好指针问题
// p=pHead;
// while( p != null){
// RandomListNode node=map.get(p);//得到新节点
// // if(p.next==null) node.next=null;
// // else node.next=map.get(p.next);
// node.next=(p.next == null)? null:map.get(p.next);
// node.random=(p.random == null)? null:map.get(p.random);
// p=p.next;
// }
// //返回新的链表头结点
// return map.get(pHead);
// }
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null) return null;
RandomListNode p=pHead;
//先将所有节点复制一遍,插入在当前节点的右侧
while( p != null){
RandomListNode node=new RandomListNode(p.label);
node.next=p.next;
p.next=node;
p=node.next;
}
//再遍历一遍,处理好左右指针问题问题
p=pHead;
while( p != null){
if(p.random !=null){
p.next.random=p.random.next;
}
p=p.next.next;
}
//分离出复制的链表
p=pHead;
RandomListNode ans=p.next;
while( p != null){
RandomListNode tmp=p.next;
p.next=tmp.next;
if(tmp.next != null){//如果tmp.next为空,则证明走到头了
tmp.next=tmp.next.next;
}
p=p.next;
}
return ans;
}
}
京公网安备 11010502036488号