链接:复制带随机节点的链表
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点,要求返回这个链表的深拷贝。
方法1:用HashMap来解决
用哈希记录对应关系,代码如下:
/*
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> map = new HashMap<>();
Node cur = head;
//将旧节点作为key,新节点作为value,放入map中
while(cur!=null){
Node node = new Node(cur.val);
map.put(cur,node);
cur= cur.next;
}
cur = head;
while(cur!=null){
//根据map中的对应关系,连接新链表
map.get(cur).next=map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur= cur.next;
}
return map.get(head);
}
}
核心代码:
map.get(cur).next=map.get(cur.next);
map.get(cur).random = map.get(cur.random);
map.get(cur)获取cur对应的值,即得到新链表的node节点, map.get(cur).next拿到node.next进行赋值,
map.get(cur.next)拿到cur.next对应的新节点,并将此赋给node.next.
random的赋值,和next赋值过程相同,不再解释。
方法2:
(1)进行关联
(2)修改新节点的random值
(3)新老节点进行交替更新
class Solution {
public Node copyRandomList(Node head) {
if(head == null){
return null;
}
//1、老新交替链接,进行一个对应关联
Node cur = head;
while(cur != null) {
Node node = new Node(cur.val,cur.next,null);
Node tmp = cur.next;
cur.next = node;
cur = tmp;
}
// 2、修改新节点的random
cur = head;
while(cur != null) {
if(cur.random != null) {
cur.next.random = cur.random.next;
cur = cur.next.next;
}else{
cur = cur.next.next;
}
}
//3、将老新节点 打开
cur = head;
Node newHead = cur.next;
while(cur.next != null) {
Node tmp = cur.next;
cur.next = tmp.next;
cur = tmp;
}
return newHead;
}
}