给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
深拷贝的意思是两个引用,分别指向到两个对象,但是这两个对象里面的内容是一样的
浅拷贝的意思是两个引用,指向的是同一个对象
这里我们采用一个比较灵活的思路:
1.创建一个HashMap,key存的是原链表的结点,value存的是新链表的结点,这两个结点是对称的。
2.把旧链表的结点依次以键值对的形式插入进来
3.再次遍历旧链表,根据刚才得到的hashMap,就能够方便的把next和random都指导正确的位置
/*
// Definition for a Node.
class Node {
public int val;
public Node next;
public Node random;
public Node() {}
public Node(int _val,Node _next,Node _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
class Solution {
public Node copyRandomList(Node head) {
//1.创建一个HashMap,key存的是原链表的结点,value存的是新链表的结点,这两个结点是对称的。
Map<Node,Node> map = new HashMap<>();
//2.把旧链表的结点依次以键值对的形式插入进来
for(Node cur = head;cur != null;cur = cur.next){
map.put(cur,new Node(cur.val,null,null));
}
//3.再次遍历旧链表,根据刚才得到的hashMap,就能够方便的把next和random都指导正确的位置
for(Node cur = head;cur != null; cur = cur.next){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
}
return map.get(head);
}
}
这道的突破口是,遍历两次原链表
第一次遍历,将原链表的结点依次放入map中的key,map中的value为新链表的结点
此时呀,这个map中有两个平行的链表,一个是key,一个是value
但是value的链表中只有结点,没有指向,所以就需要再遍历一次
第二次遍历,根据key找到value的结点,指向下一个key对应value的结点,就完成了.next的操作