1. // 使用额外空间:使用hash表,key是老节点,value是新节点。
    2. // 遍历老节点,并取出对应value新节点,然后获得老节点next,
    3. // 再从hash表中找出老节点next的value,新节点next就是这个value。rand也是这样。
    4. public static Node copyRandomList1(Node head) {
    5. // key 老节点
    6. // value 新节点
    7. HashMap<Node, Node> map = new HashMap<Node, Node>();
    8. Node cur = head;
    9. while (cur != null) {
    10. map.put(cur, new Node(cur.val));
    11. cur = cur.next;
    12. }
    13. cur = head;
    14. while (cur != null) {
    15. // cur 老
    16. // map.get(cur) 新
    17. // 新.next -> cur.next克隆节点找到
    18. map.get(cur).next = map.get(cur.next);
    19. map.get(cur).random = map.get(cur.random);
    20. cur = cur.next;
    21. }
    22. return map.get(head);
    23. }
    24. // 老节点挂在新节点的next,然后新节点next指向老节点next。然后循环一对一对的设置rand。
    25. // 新节点的rand就是老节点的rand的next,最后新老链表分离。利用新节点的位置关系实现了一一对应。1→1'→2→2’
    26. public static Node copyRandomList2(Node head) {
    27. if (head == null) {
    28. return null;
    29. }
    30. Node cur = head;
    31. Node next = null;
    32. // 1 -> 2 -> 3 -> null
    33. // 1 -> 1' -> 2 -> 2' -> 3 -> 3'
    34. while (cur != null) {
    35. next = cur.next; // 保留当前节点后驱
    36. cur.next = new Node(cur.val); // 当前节点后驱指向当前复制节点
    37. cur.next.next = next;
    38. cur = next;
    39. }
    40. cur = head;
    41. Node copy = null;
    42. // 1 1' 2 2' 3 3'
    43. // 依次设置 1' 2' 3' random指针
    44. while (cur != null) {
    45. next = cur.next.next;
    46. copy = cur.next;
    47. // 当前节点的随机节点下一个就是复制节点的随机节点
    48. copy.random = cur.random != null ? cur.random.next : null;
    49. cur = next;
    50. }
    51. Node res = head.next;
    52. cur = head;
    53. // 老 新 混在一起,next方向上,random正确
    54. // next方向上,把新老链表分离
    55. while (cur != null) {
    56. next = cur.next.next;
    57. copy = cur.next;
    58. cur.next = next;
    59. copy.next = next != null ? next.next : null;
    60. cur = next;
    61. }
    62. return res;
    63. }