0138. Copy List with Random Pointer (M)

Copy List with Random Pointer (M)

题目

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:

  • val: an integer representing Node.val
  • random_index: the index of the node (range from 0 to n-1) where random pointer points to, or null if it does not point to any node.

Example 1:

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]

Example 2:

Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]

Example 3:

Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]

Example 4:

Input: head = []
Output: []
Explanation: Given linked list is empty (null pointer), so return null.

Constraints:

  • -10000 <= Node.val <= 10000
  • Node.random is null or pointing to a node in the linked list.
  • Number of Nodes will not exceed 1000.

题意

给定一个链表,该链表中有next和random两个域,next指向链表的下一个结点,random指向链表中随机一个结点或为null。要求返回该链表的一个深拷贝。

思路

拷贝next容易,难在拷贝random。问题的关键在于如何建立新旧链表对应结点之间的关系。

一种非常巧妙地方法是,每次拷贝一个结点A'后,将其插入到旧链表对应结点A之后,以此建立对应关系A->A',即A.next = A'。如果有A.random = B,且A'.random = B',根据之前建立的对应关系还能得到B.next = B',所以很容易发现A'.random = A.random.next。拷贝完所有的random后,只要再将新旧链表拆分出来即可。

也可以使用HashMap来绑定新旧结点,这样更加直观一点。


代码实现

Java

链表交叉

class Solution {
    public Node copyRandomList(Node head) {
        // 将新结点交叉插入到旧链表中
        Node p = head;
        while (p != null) {
            Node temp = new Node(p.val);
            temp.next = p.next;
            p.next = temp;
            p = temp.next;
        }
        
        // 生成新链表的random域
        p = head;
        while (p != null) {
            Node q = p.next;
            q.random = p.random == null ? null : p.random.next;		// null单独处理
            p = q.next;
        }
        
        // 拆分新旧链表
        p = head;
        Node dummy = new Node(0);
        Node cur = dummy;
        while (p != null) {
            cur.next = p.next;
            cur = cur.next;
            p.next = cur.next;
            p = p.next;
            cur.next = null;
        }
        
        return dummy.next;
    }
}

Hash

class Solution {
    public Node copyRandomList(Node head) {
        Map<Node, Node> hash = new HashMap<>();
        Node p = head;
        Node dummy = new Node(0);
        Node cur = dummy;
        
        // 生成hash对应关系
        while (p != null) {
            cur.next = new Node(p.val);
            cur = cur.next;
            hash.put(p, cur);
            p = p.next;
        }
        
        // 根据对应关系生成新链表的random域
        p = head;
        while (p != null) {
            hash.get(p).random = p.random == null ? null : hash.get(p.random);	// null单独处理
            p = p.next;
        }
        
        return dummy.next;
    }
}

JavaScript

/**
 * @param {Node} head
 * @return {Node}
 */
var copyRandomList = function (head) {
  let p = head
  while (p) {
    p.next = new Node(p.val, p.next, null)
    p = p.next.next
  }
  p = head
  while (p) {
    p.next.random = p.random ? p.random.next : null
    p = p.next.next
  }
  const dummy = new Node(0, null, null)
  p = dummy
  while (head) {
    p.next = head.next
    p = p.next
    head.next = head.next.next
    head = head.next
  }
  return dummy.next
}
posted @ 2021-02-10 17:05  墨云黑  阅读(58)  评论(0编辑  收藏  举报