题目:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
分析1(推荐-易理解):
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
//给定一组链表,每个节点的下标包含下一个和一个随机指向的节点,返回其复制的值
//思路:使用hashmap存储每个节点next的信息,再遍历一遍实现rand的拼接
if(head==null)return null;
HashMap<RandomListNode,RandomListNode> hm =new HashMap<>();
RandomListNode dummy=new RandomListNode(0);
RandomListNode node=dummy,p=head;
while(head!=null){
//复制当前节点
RandomListNode cur=new RandomListNode(head.label);
//cur为当前复制节点的信息
hm.put(head,cur);
head=head.next;
node.next=cur;
node=node.next;
}
//再遍历一遍
node=dummy.next;
while(p!=null){
if(p.random!=null){
//查找当前节点的random,上面已经包含一个节点信息的hash表,直接通过hash查找
node.random=hm.get(p.random);
}
p=p.next;
node=node.next;
}
return dummy.next;
}
}
分析2:
图解:
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
//给定一组链表,每个节点的下标包含下一个和一个随机指向的节点,返回其复制的值
//思路:直接复制节点,并将拷贝后的节点放到原节点后面,更新所有拷贝的节点的random节点,将原链表与复制链表断开
if(head==null) return null;
RandomListNode h=head;
//复制节点
while(h!=null){
RandomListNode copy=new RandomListNode(h.label);
RandomListNode next=h.next;
h.next=copy;
copy.next=next;
h=next;
}
//更新random
h=head;
while(h!=null){
if(h.random!=null){
//h.random.next指的是新的random
h.next.random=h.random.next;
}
h=h.next.next;
}
//断链
h=head;
RandomListNode dummy=h.next;
while(h!=null){
RandomListNode cur=h.next;
h.next=cur.next;
h=h.next;
cur.next=h==null?null:h.next;
}
return dummy;
}
}