Copy list with random Pointer in Python

A Linked List with Random Pointers is a data structure where each node contains data, a next pointer, and an additional random pointer that can point to any node in the list. Creating a deep copy of such a list requires preserving both the structure and random pointer relationships.

The challenge is to copy not just the values and next pointers, but also maintain the correct random pointer connections in the new list.

Problem Example

Consider a linked list where each node has a random pointer:

1 2 3 4 Random Pointers Next Pointers

Algorithm Approach

The solution uses a three-step approach:

  1. Insert Copy Nodes: Create a duplicate node after each original node
  2. Set Random Pointers: Copy random pointer relationships to new nodes
  3. Separate Lists: Extract the copied list from the interleaved structure

Implementation

class ListNode:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.random = None

def copyRandomList(head):
    if head is None:
        return head
    
    # Step 1: Insert a new node after each original node
    curr = head
    while curr != None:
        new_node = ListNode(curr.data)
        new_node.next = curr.next
        curr.next = new_node
        curr = new_node.next
    
    # Step 2: Set random pointers for new nodes
    curr = head
    while curr != None:
        if curr.random:
            curr.next.random = curr.random.next
        curr = curr.next.next
    
    # Step 3: Separate the lists
    curr = head
    copied_head = head.next
    while curr.next != None:
        temp = curr.next
        curr.next = curr.next.next
        curr = temp
    
    return copied_head

def printList(head):
    curr = head
    while curr != None:
        random_data = curr.random.data if curr.random else "None"
        print(f"Data: {curr.data}, Random: {random_data}")
        curr = curr.next

# Create original list
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
head.next.next.next.next = ListNode(5)

# Set random pointers
head.random = head.next.next  # 1 -> 3
head.next.random = head  # 2 -> 1
head.next.next.random = head.next.next.next.next  # 3 -> 5
head.next.next.next.random = head.next.next.next.next  # 4 -> 5
head.next.next.next.next.random = head.next  # 5 -> 2

print("Original list:")
printList(head)

copied_list = copyRandomList(head)
print("\nDeep Copy of the List:")
printList(copied_list)
Original list:
Data: 1, Random: 3
Data: 2, Random: 1
Data: 3, Random: 5
Data: 4, Random: 5
Data: 5, Random: 2

Deep Copy of the List:
Data: 1, Random: 3
Data: 2, Random: 1
Data: 3, Random: 5
Data: 4, Random: 5
Data: 5, Random: 2

How It Works

The algorithm creates an interleaved list where each original node is followed by its copy. This allows us to easily map random pointers: if original node A points to node B, then copy of A should point to copy of B (which is B.next in the interleaved list).

Time and Space Complexity

Complexity Value Explanation
Time O(n) Three passes through the list
Space O(1) No additional data structures needed

Conclusion

The interleaving approach efficiently creates a deep copy of a linked list with random pointers in O(n) time and O(1) extra space. This method preserves all pointer relationships without requiring hash maps or additional memory for tracking node mappings.

Updated on: 2026-03-25T16:44:54+05:30

832 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements