* * 复制含有随机指针的链表 * * 思路1: 每遍历一次旧节点存入到map一个新的节点(不需要设置),然后依据来节点的指向设置 * 思路2: 复制节点,由原节点指向,然后拆分 * * 箭头矢代表random指向 * -----------> * 7 -> 23 -> 3 -> 4 -> 56 * <----- *
//思路1: 每遍历一次旧节点存入到map一个新的节点(不需要设置),然后依据来节点的指向设置
public Node copyLinkWithMap(Node head){
if(head != null){
HashMap<Node,Node> map = new HashMap<>();
Node curr = head;
//2 ,5 ,1 ,7
while (curr != null){
map.put(curr, new Node(curr.val));
curr = curr.next;
}
curr = head;
while (curr != null){
map.get(curr).next = map.get(curr.next);
map.get(curr).rand = map.get(curr.rand);
curr = curr.next;
}
return map.get(head);
}
return null;
}
//思路2: 复制节点,由原节点指向,然后拆分
public Node copyLinkWithClone(Node head){
if(head != null){
Node curr = head;
Node next;
//将copy节点接在元节点下
while (curr != null){
next = curr.next;
//copy一个纯净的节点
Node cp = new Node(curr.val);
curr.next = cp;
cp.next = next;
curr = next;
}
//设置rand指针
curr = head;
next = head.next;
while (curr != null){
next.rand = curr.rand == null ? null : curr.rand.next;
next = next.next == null ? null : next.next.next;
curr = curr.next.next;
}
//split
curr = head;
next = head.next;
Node copy = next;
/*
箭头矢代表rand指向
----------------->
7 -> 7 -> 23 -> 23 -> 3 -> 3 -> 4 -> 4 -> 56 -> 56
<----------
*/
while (curr != null){
curr.next = next.next;
curr = curr.next;
//注意空指针问题
next.next = next.next == null ? null : next.next.next;
next = next.next;
}
return copy;
}
return null;
}
private static class Node{
public int val;
public Node next;
public Node rand; //随即指针
public Node(int val) {
this.val = val;
}
}
左神算法学习