方法一:用map来做是思路最简单的。
1.首先根据原链表,复制一份一模一样的链表节点存到map中。其中键为原链表的节点,值为复制后的节点。
2.根据原链表的指向关系,去构建map中复制链表节点的结构。

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
import java.util.*;
public class Solution {
    public RandomListNode Clone(RandomListNode head) {
         if (head == null) return null;

        HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
        RandomListNode cur = head;
        while (cur != null){
            map.put(cur,new RandomListNode(cur.label));
            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);
    }
}

方法二:在原链表的基础上构建映射关系。空间复杂度小。
1.先复制每个节点,创建next映射关系,然后在搭建复制节点的random映射关系;
2.将原链表与复制链表的next关系分离开来。

/*
public class Node {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode head) {
         if (head == null) return null;
        RandomListNode cur = head;
        RandomListNode next = null;
        //复制节点,并将复制后的节点挂到原节点的后面
        // 1--->2
        // 1--->1'--->2
        while (cur != null){
            next = cur.next; //先将原来的cur的下一节点保存起来
            cur.next = new RandomListNode(cur.label);
            cur.next.next = next;
            cur = next;
        }
        //
        cur = head;//从头开始构建映射关系(复制后节点random的指向关系)
        RandomListNode curCopy = null; //表示当前节点的复制节点
        while (cur != null){
            next = cur.next.next;
            curCopy = cur.next;
            curCopy.random = cur.random != null ? cur.random.next:null;
            cur = next;
        }
        //进行分离操作random上的指针不需要再改动了,只需要将next指针进行分离即可。
        RandomListNode resHead = head.next;//保存最后需要返回的头节点(就是原头节点后的复制节点)
        cur = head;
        while (cur != null){
            next = cur.next;//保存当前节点的下一个节点(即复制节点)
            cur.next = next.next; //让复制节点的下一个节点(即原节点的下一个节点)挂在当前节点下(恢复原来的位置)
            next.next = next.next != null ? next.next.next:null;//若复制节点的下一节点不为空(那么一定有下一个复制节点),将其挂在前一个复制节点后
            cur = cur.next; // 后移cur
        }
        return resHead;
    }
}