题目

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 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/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

1.hash

  1. /**
  2. * // Definition for a Node.
  3. * function Node(val, next, random) {
  4. * this.val = val;
  5. * this.next = next;
  6. * this.random = random;
  7. * };
  8. */
  9. /**
  10. * @param {Node} head
  11. * @return {Node}
  12. */
  13. var copyRandomList = function (head) {
  14. // hash
  15. const store = new Map()
  16. for (let cur = head; cur !== null; cur = cur.next) {
  17. store.set(cur, new Node(cur.val))
  18. }
  19. for (let cur = head; cur !== null; cur = cur.next) {
  20. cur.next ? store.get(cur).next = store.get(cur.next) : store.get(cur).next = null
  21. store.get(cur).random = store.get(cur.random)
  22. }
  23. return store.get(head)
  24. };

2.原地
将原右节点复制一份连接在后面,然后再切分成2个链表

  1. /**
  2. * // Definition for a Node.
  3. * function Node(val, next, random) {
  4. * this.val = val;
  5. * this.next = next;
  6. * this.random = random;
  7. * };
  8. */
  9. /**
  10. * @param {Node} head
  11. * @return {Node}
  12. */
  13. var copyRandomList = function (head) {
  14. // 原地深拷贝
  15. if (!head) return head
  16. // 复制 node
  17. for (let cur = head; cur !== null; cur = cur.next.next) {
  18. const node = new Node(cur.val)
  19. node.next = cur.next
  20. cur.next = node
  21. }
  22. // 连接 random
  23. for (let cur = head; cur !== null; cur = cur.next.next) {
  24. cur.random ? cur.next.random = cur.random.next : cur.next.random = null
  25. }
  26. let old_head = head
  27. let new_head = head.next
  28. let res = new_head
  29. while (old_head) {
  30. old_head.next = old_head.next.next
  31. old_head = old_head.next
  32. new_head.next ? new_head.next = new_head.next.next : new_head.next = null
  33. new_head = new_head.next
  34. }
  35. return res
  36. };