Clone the Linked List with Random and Next Pointer in Python

A linked list is created using a random pointer. Given an N-by-N linked list, where each node has two connections, one pointing to the node after it and the other to any node in the list. We have to duplicate this linked list in O(N) time.

Recall that the "next" pointer points to the next node in the linked list, but the "random" pointer might point to any node in the linked list at random.

Approach - 1

The new nodes are then mapped to their corresponding nodes in the existing linked list by first creating a singly linked list with just the 'next' pointer. You may now use any node in the freshly formed list to point to the arbitrary node using this mapping.

Here is the algorithmic approach to the above idea:

  • For each node (say N1), replicate it (say N2), then map it to its associated old node (say map), such that map[N1] equals N2.
  • Make a single linked list of duplicate nodes with only the 'next' pointer for each node.
  • Repeat these steps for the previous linked list iterations:
    • Find the duplicate node that is mapped to the existing one. (For example, map[N1] is the duplicate if the current node is N1.)
    • Make the current -> random node's duplicate's random pointer point to the duplicate of that node (such that map[N1] -> random points to map[N1 -> random]).
  • This method produces the required clone of the linked list.

Code

Output:

The initial linked list is as follows:
2(9) -> 6(2) -> 9(15) -> 13(9) -> 15(6)

2 : 2, 6 : 6, 9 : 9, 13 : 13, 15 : 15

The clone of the linked list is:
2(9) -> 6(2) -> 9(15) -> 13(9) -> 15(6)

Time Complexity: The time complexity of this program is O(N), where N is the number of nodes in the linked list. We have not used any nested loop and hence traversed the linked list linearly; therefore, the time complexity is also linear.

Auxiliary Space: The space complexity of the program is also O(N). The space complexity is linear because we are creating a new linked list.

Approach - 2 (Optimizing the Space Complexity)

Below is the method to optimize the space complexity of the program:

We will create a duplicate node and store it in between the actual node and the node next to it.

This implies that for a node N, we will create a node having the same value as N and store it as N -> next. This node will serve as the duplicate node. The random pointer of the duplicate node will point to the N -> random -> next, as it is the duplicate of N -> random.

Below is the algorithmic approach to the above idea:

  • We will create a copy of node N1 and store it in between the nodes N1 and N2 in the initial linked list. Likewise, we will create a copy of the node N2 and store it in between the nodes N2 and N3 and so on. In simple words, we will create and duplicate the node of node N and insert it after the Nth node.
  • Now we will copy the random link this way:
    • node -> next -> random = node -> random -> next
  • Then we will separate the original and clone of the linked list in a single linear loop.
    • node -> next = node -> next -> next
    • clone -> next = clone -> next -> next

Code

Output:

The initial linked list is as follows:
2 ( 9 ) -> 6 (2) -> 9 (15) -> 13 (9) -> 15 (6)
The clone of the linked list is:
2 ( 9 ) -> 6 (2) -> 9 (15) -> 13 (9) -> 15 (6)

Time Complexity: The time complexity of this program is also O(N). We are linearly traversing through the linked list, and hence the time complexity is also linear.

Auxiliary Space: Since we have not created any mapping in this approach and only stored the node objects in the original linked list therefore, the space complexity of this approach is constant. The space complexity is O(1).