思路
步骤
1、第一次遍历链表
完成k-v映射(k是原链表节点,v是创建的新链表节点:只有值,没有next和random属性)
2、第二次遍历链表
完成v的next和random属性的填充
因为原节点和新节点是一一对应的关系,如图:
- map.get(原节点),得到的就是对应的新节点
- map.get(原节点.next),就是我们想要的新节点.next
old1.next是old2
map.get(old1.next) => map.get(old2) 即 new2
所以,new1.next = new2
- map.get(原节点.random),就是我们想要的新节点.random
old1.random时old3
map.get(old1.random) => map.get(old3) 即new3
所以,new1.random = new3
public class CopyComplexLink {
public static void main(String[] args) {
// head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Node head = new Node(7);
Node n1 = new Node(13);
Node n2 = new Node(11);
Node n3 = new Node(10);
Node n4 = new Node(1);
head.next = n1;
n1.next = n2;
n2.next = n3;
n3.next = n4;
head.random = null;
n1.random = head;
n2.random = n4;
n3.random = n2;
n4.random = head;
Node res = copyRandomList(head);
System.out.println(res);
}
public static Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// 1.第一遍遍历,设置k-v
Map<Node, Node> old2NewMap = new HashMap<>();
Node temp = head;
while (temp != null) {
old2NewMap.put(temp, new Node(temp.val));
temp = temp.next;
}
// 2.第二遍遍历,设置v的next和random
temp = head;
while (temp != null) {
Node newNode = old2NewMap.get(temp);
newNode.next = old2NewMap.get(temp.next);
newNode.random = old2NewMap.get(temp.random);
temp = temp.next;
}
return old2NewMap.get(head);
}
}
Node
public class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}