给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
    要求返回这个链表的 深拷贝。
    我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
    val:一个表示 Node.val 的整数。
    random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
    示例 1:
    138.复制带随机指针的链表——medium - 图1

    输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
    输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

    示例 2:
    138.复制带随机指针的链表——medium - 图2

    输入:head = [[1,1],[2,1]]
    输出:[[1,1],[2,1]]

    示例 3:
    138.复制带随机指针的链表——medium - 图3

    输入:head = [[3,null],[3,0],[3,null]]
    输出:[[3,null],[3,0],[3,null]]

    示例 4:
    **
    输入:head = []
    输出:[]
    解释:给定的链表为空(空指针),因此返回 null。

    提示:

    • -10000 <= Node.val <= 10000
    • Node.random 为空(null)或指向链表中的节点。
    • 节点数目不超过 1000 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer

    1. /**
    2. *1.遍历链表,复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
    3. *2.因为random可能会指向一个还未创建的新节点,所以先把A和A1保存在Map中;
    4. *3.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random;
    5. *时间复杂度O(n)
    6. *空间复杂度O(n)
    7. */
    8. var copyRandomList = function (head) {
    9. if (!head) {
    10. return null;
    11. }
    12. const map = new Map();
    13. let curNode = head;
    14. //1.复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
    15. while (curNode) {
    16. let newNode = new Node(curNode.val);
    17. //2.因为random可能会指向一个还未创建的新节点,所以先把A和A1保存在Map中;
    18. map.set(curNode, newNode);
    19. curNode = curNode.next
    20. }
    21. curNode = head;
    22. //3.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random;
    23. while (curNode) {
    24. let newNode = map.get(curNode);
    25. newNode.next = curNode.next &&map.get(curNode.next)
    26. newNode.random = curNode.random && map.get(curNode.random);
    27. curNode = curNode.next
    28. }
    29. return map.get(head);
    30. };
    31. /**
    32. *1.复制每个节点,如:复制节点A得到A1,将A1插入节点A后面
    33. *2.重新遍历链表,A1->random = A->random->next;
    34. *3.将链表拆分成原链表和复制后的链表
    35. *时间复杂度O(n)
    36. *空间复杂度O(1)
    37. */
    38. var copyRandomList = function (head) {
    39. if (!head) {
    40. return null;
    41. }
    42. let curNode = head;
    43. //1.复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
    44. while (curNode) {
    45. let cloneNode = new Node(curNode.val);
    46. let nextNode = curNode.next;
    47. curNode.next = cloneNode;
    48. cloneNode.next = nextNode;
    49. curNode = nextNode;
    50. }
    51. curNode = head;
    52. //2.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random;
    53. while (curNode) {
    54. curNode.next.random = curNode.random && curNode.random.next;
    55. curNode = curNode.next.next;
    56. }
    57. //3.将链表拆分成原链表和复制后的链表
    58. curNode = head;
    59. let cloneHead = head.next;
    60. while (curNode) {
    61. let cloneNode = curNode.next;
    62. curNode.next = cloneNode.next;
    63. cloneNode.next = cloneNode.next && cloneNode.next.next;
    64. curNode = curNode.next;
    65. }
    66. return cloneHead;
    67. };