138. Copy List with Random Pointer

Problem:

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.

思路1

Solution:

Node* copyRandomList(Node* head) {
    Node *newHead, *l1, *l2;
    if (head == NULL)  return NULL;
    for (l1 = head; l1 != NULL; l1 = l1->next->next) {
        l2 = new Node(l1->val);
        l2->next = l1->next;
        l1 -> next = l2;
    }
    
    newHead = head->next;
    for (l1 = head; l1 != NULL; l1 = l1->next->next) {
        if (l1->random != NULL)  l1->next->random = l1->random->next;
    }
    for (l1 = head; l1 != NULL; l1 = l1->next) {
        l2 = l1->next;
        l1->next = l2->next;
        if (l2->next != NULL)  l2->next = l2->next->next;
    }
    return newHead;
}

性能:
Runtime: 16 ms  Memory Usage: 11.1 MB

思路2

建立一个哈希表unordered_map<Node*, Node*>,key值为指向原链表结点的指针,value为指向复制链表结点的指针,首先遍历原链表,复制出新的链表并用next指针连接。然后遍历原链表,用random指针连接。

Solution (C++):

Node* copyRandomList(Node* head) {
    if (!head)  return NULL;
    using N = Node*;
    unordered_map<N, N> hash;
    N old_head = head;
    N new_head = new Node(head->val);
    hash[old_head] = new_head;
    while (old_head->next) {
        new_head->next = new Node(old_head->next->val);
        old_head = old_head->next;
        new_head = new_head->next;
        hash[old_head] = new_head;
    }
    old_head = head;
    new_head = hash[old_head];
    
    while (old_head && new_head) {
        new_head->random = old_head->random ? hash[old_head->random] : NULL;
        old_head = old_head->next;
        new_head = new_head->next;
    }
    
    return hash[head];
}

性能

Runtime: 12 ms  Memory Usage: 11.1 MB

思路3

思路2的简化版本。

Solution (C++):

Node* copyRandomList(Node* head) {
    if (!head)  return NULL;
    Node *newHead, *l1 = head, *l2;
    for (l1; l1; l1 = l1->next->next) {
        l2 = new Node(l1->val);
        l2->next = l1->next;
        l1 -> next = l2;
    }

    newHead = head->next;
    for (l1 = head; l1; l1 = l1->next->next) {
        if (l1->random)  l1->next->random = l1->random->next;
    }
    for (l1 = head; l1; l1 = l1->next) {
        l2 = l1->next;
        l1->next = l2->next;
        if (l2->next)  l2->next = l2->next->next;
    }
    return newHead;
}

性能

Runtime: 12 ms  Memory Usage: 11.1 MB

posted @ 2020-02-09 10:44  littledy  阅读(113)  评论(0编辑  收藏  举报