Skip to content

Commit d6665e1

Browse files
committed
streak day 1: clone list with random ptrs
1 parent 6175022 commit d6665e1

File tree

3 files changed

+136
-7
lines changed

3 files changed

+136
-7
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
| Current Status| Stats |
88
| :------------: | :----------: |
99
| Total C++ Problems | 188 |
10-
| Total Python Problems | 5 |
11-
| Current Daily Streak| 1 |
10+
| Total Python Problems | 6 |
11+
| Current Daily Streak| 2 |
1212
| Last Streak | 06/20/2019 - 06/21/2019|
13-
| Current Streak | 06/23/2019 - |
13+
| Current Streak | 06/23/2019 - 06/24/2019|
1414

1515
</center>
1616

@@ -30,7 +30,7 @@
3030
| Determine if a linked list is a pallindrome. | [listPallindrome.cpp](linked_list_problems/listPallindrome.cpp) |
3131
| Insert data in a sorted linked list.|[insertInASortedLinkedList.cpp](linked_list_problems/insertInASortedLinkedList.cpp) |
3232
| Determine the intersection(merging) point of two given linked list.| [findIntersectionPointOfLists.cpp](linked_list_problems/findIntersectionPointOfLists.cpp)|
33-
| Clone a linkedlist which has next and an random pointer, Space Complexity - O(1). | [cloneListWithRandomPtr.cpp](linked_list_problems/cloneListWithRandomPtr.cpp)|
33+
| Clone a linkedlist which has next and an random pointer, Space Complexity - O(1). | [cloneListWithRandomPtr.cpp](linked_list_problems/cloneListWithRandomPtr.cpp), [clone_list_with_random_ptr.py](linked_list_problems/clone_list_with_random_ptr.py)|
3434
| Given a sorted linked list with duplicates, remove duplicates in one iteration. | [removeDuplicatesFromSortedList.cpp](linked_list_problems/removeDuplicatesFromSortedList.cpp)|
3535
| Using Floyd's cycle finding algorithm, detect if a linkedlist contain cycle, if it does contain cycle, remove the loop | [floyedCycleDetection.cpp](linked_list_problems/floyedCycleDetection.cpp) |
3636
| Sort a linked list using merge sort | [merge_sort.cpp](linked_list_problems/merge_sort.cpp) |
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
Given a list with next and random pointer, clone this list
3+
"""
4+
5+
class Node:
6+
def __init__(self, data):
7+
"""Representation of a linked list Node"""
8+
self.data = data
9+
self.next = None
10+
self.random = None
11+
12+
def set_random(self, random_node):
13+
self.random = random_node
14+
15+
16+
class LinkedList:
17+
def __init__(self):
18+
"""Representation of a linked list"""
19+
self.head = None
20+
21+
def push(self, data):
22+
""" Pushes a node at the top of linked list and make it head"""
23+
node = Node(data)
24+
node.next = self.head
25+
self.head = node
26+
27+
28+
def get_head(self):
29+
return self.head
30+
31+
def set_head(self, head):
32+
self.head = head
33+
34+
def print_list(self):
35+
""" Prints a list, random node pointers are enclosed in brackets """
36+
itr = self.head
37+
while itr:
38+
random_data = 'None' if itr.random is None else str(itr.random.data)
39+
if itr.next is None:
40+
print(str(itr.data) + '('+ random_data +')')
41+
else:
42+
print(str(itr.data) + '('+ random_data +') -->', end=' ')
43+
itr = itr.next
44+
45+
def clone(self):
46+
""" Clones a list with random pointers and return a new list back"""
47+
48+
# add a new node after each node with same data.
49+
new_list = LinkedList()
50+
itr = self.head
51+
while itr:
52+
new_node = Node(itr.data)
53+
next_node = itr.next
54+
itr.next = new_node
55+
new_node.next = next_node
56+
itr = next_node
57+
58+
# create random pointers for the new nodes.
59+
itr = self.head
60+
while itr:
61+
itr.next.random = None if itr.random is None else itr.random.next
62+
itr = itr.next.next
63+
64+
# separte the lists now.
65+
new_head = self.head.next
66+
itr1 = self.head
67+
itr2 = self.head.next
68+
while itr1.next and itr2.next:
69+
itr1.next = itr1.next.next
70+
itr2.next = itr2.next.next
71+
itr1 = itr1.next
72+
itr2 = itr2.next
73+
74+
new_list.set_head(new_head)
75+
return new_list
76+
77+
def verify_clone(self, list2):
78+
itr1 = self.head
79+
itr2 = list2.get_head()
80+
81+
while itr1 and itr2:
82+
if itr1.data != itr2.data:
83+
return False
84+
if (itr1.random and not itr2.random) or \
85+
(itr2.random and not itr1.random):
86+
return False
87+
if itr1.random and itr2.random:
88+
if itr1.random.data != itr2.random.data:
89+
return False
90+
itr1 = itr1.next
91+
itr2 = itr2.next
92+
93+
return True
94+
95+
96+
if __name__ == "__main__":
97+
list1 = LinkedList()
98+
list1.push(5)
99+
list1.push(4)
100+
list1.push(3)
101+
list1.push(2)
102+
list1.push(1)
103+
104+
head = list1.get_head()
105+
head.random = head.next.next
106+
head.next.random = head
107+
head.next.next.random = head.next.next.next.next
108+
head.next.next.next.random = head.next.next
109+
head.next.next.next.next.random = head.next
110+
print("Original list:")
111+
list1.print_list()
112+
113+
print("New list:")
114+
list2 = list1.clone()
115+
list2.print_list()
116+
117+
print("Are lists identical? : ", list1.verify_clone(list2))

linked_list_problems/swap_nodes_without_swapping_data.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ def print_list(self):
3232
print(str(itr.data) + '-->', end = ' ')
3333
itr = itr.next
3434

35+
def print_list_addr(self):
36+
"""Prints a list with address of the next pointer"""
37+
itr = self.head
38+
while itr:
39+
if itr.next is None:
40+
print(str(itr.data) + '(' + str(hex(id(itr))) + ')')
41+
else:
42+
print(str(itr.data) + '(' + str(hex(id(itr))) + ') --> ', end=' ')
43+
itr = itr.next
44+
3545
def swap_nodes_without_swapping_data(self, x, y):
3646
"""Swap the nodes of linked without swapping pointers i.e.
3747
swap nodes such that nodes with data x will contain y and vice versa."""
@@ -84,9 +94,11 @@ def swap_nodes_without_swapping_data(self, x, y):
8494
lst.push(2)
8595
lst.push(4)
8696

87-
print("List before:")
97+
print("List before (with and without addr):")
8898
lst.print_list()
99+
lst.print_list_addr()
89100

90101
lst.swap_nodes_without_swapping_data(1, 4)
91-
print("List after:")
92-
lst.print_list()
102+
print("List after (with and without addr):")
103+
lst.print_list()
104+
lst.print_list_addr()

0 commit comments

Comments
 (0)