Thursday, May 21, 2015

[Flipkart][LeetCode] Copy List with Random Pointer

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

Construct a deep copy of the list. The deep copy should consist of exactly n brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next and random pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list.

For example, if there are two nodes X and Y in the original list, where X.random --> Y, then for the corresponding two nodes x and y in the copied list, x.random --> y.

Return the head of the copied linked 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) that the random pointer points to, or null if it does not point to any node.
Your code will only be given the head of the original linked list.

Example:

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

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

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

Approach:
  1. Create the copy each node in the list and insert it between node and its next.
  2. Now copy the random pointer as follows:
    • node->next->random = node->random->next
  3. Restore the original and copy linked lists as follows:
    • original->next = original->next->next
    • copy->next = copy->next->next


Implementation in C#:

    public Node CopyRandomList(Node head)
    {
        if (head == null)
        {
            return null;
        }
        Node node = head;
        while (node != null)
        {
            Node next = node.next;
            node.next = new Node(node.val);
            node.next.next = next;
            node = next;
        }
        node = head;
        while (node != null)
        {
            node.next.random = node.random?.next;
            node = node.next.next;
        }
        node = head;
        Node copyHead = node.next;
        Node copyNode = copyHead;
        while (node != null)
        {
            node.next = node.next.next;
            copyNode.next = copyNode.next?.next;
            node = node.next;
            copyNode = copyNode.next;
        }
        return copyHead;    
    }


Complexity: O(n)

4 comments:

  1. Nice Solution. It would be even better if you can explain how you came up with this approach.

    ReplyDelete
    Replies
    1. I was thinking for the hashing but I realized that Linked List Node have the property "next" and I can use next instead of hashing.

      Delete
  2. wat is random pointer
    struct llist
    {
    int data;
    struct llist *next;
    struct llist *random;
    }
    or wat is random pointer

    ReplyDelete
    Replies
    1. Hi Awadhesh,
      Random pointer is a pointer which can point to any node in the list. See the problem statement

      Delete