Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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:
Algorithm Approach
The solution uses a three-step approach:
- Insert Copy Nodes: Create a duplicate node after each original node
- Set Random Pointers: Copy random pointer relationships to new nodes
- 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.
