给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的深拷贝。 

 

示例:

273,复制带随机指针的链表_指针

输入:{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

节点的数据结构

 1class Node {
2    public int val;
3    public Node next;
4    public Node random;
5
6    public Node() {
7    }
8
9    public Node(int _val, Node _next, Node _random) {
10        val = _val;
11        next = _next;
12        random = _random;
13    }
14}

答案:

 1public Node copyRandomList(Node head) {
2    HashMap<Node, Node> nodemap = new HashMap<Node, Node>();
3    return copyListHelper(head, nodemap);
4}
5
6public Node copyListHelper(Node head, HashMap<Node, Node> nodemap) {
7    if (head == null) return null;
8    if (nodemap.containsKey(head))
9        return nodemap.get(head);
10    Node ret = new Node(head.val);
11    nodemap.put(head, ret);
12    ret.next = copyListHelper(head.next, nodemap);
13    ret.random = copyListHelper(head.random, nodemap);
14    return ret;
15}

解析:
使用递归的方式,代码比较简单,就不再介绍。再来看一种非递归的解法

 1public Node copyRandomList(Node head) {
2    if (head == null) return null;
3    Map<Node, Node> map = new HashMap<Node, Node>();
4    Node node = head;
5    while (node != null) {
6        map.put(node, new Node(node.val));
7        node = node.next;
8    }
9    node = head;
10    while (node != null) {
11        map.get(node).next = map.get(node.next);
12        map.get(node).random = map.get(node.random);
13        node = node.next;
14    }
15    return map.get(head);
16}

第一个while循环是创建所有的Node,第二个while循环是为了把上面创建的Node连接起来。