@@ -28,6 +28,13 @@ def __eq__(self, other: object):
28
28
return NotImplemented
29
29
return self .data == other .data
30
30
31
+ def __hash__ (self ):
32
+ """
33
+ Hash based on node's memory address.
34
+ :return:
35
+ """
36
+ return id (self )
37
+
31
38
32
39
class LinkedList :
33
40
def __init__ (self , * numbers : int ):
@@ -153,6 +160,29 @@ def __eq__(self, other: object):
153
160
return a is None and b is None
154
161
155
162
163
+ def intersection_linear_runtime (ll1 : LinkedList , ll2 : LinkedList ) -> Optional [Node ]:
164
+ """
165
+ This function will determine if ll1 and ll2 intersect.
166
+ The intersection is defined based on reference, not value.
167
+ Runtime: O(n)
168
+ Space Complexity: O(n)
169
+ :param ll1: first input linked list
170
+ :param ll2: second input linked list
171
+ :return: The intersecting node or None
172
+ """
173
+ n1 = ll1 .head
174
+ refs = set ()
175
+ while n1 is not None :
176
+ refs .add (n1 )
177
+ n1 = n1 .next
178
+ n2 = ll2 .head
179
+ while n2 is not None :
180
+ if n2 in refs :
181
+ return n2
182
+ n2 = n2 .next
183
+ return None
184
+
185
+
156
186
def intersection (ll1 : LinkedList , ll2 : LinkedList ) -> Optional [Node ]:
157
187
"""
158
188
This function will determine if ll1 and ll2 intersect.
@@ -240,6 +270,14 @@ def test_intersections(self):
240
270
for ll1 , ll2 in self .no_intersection_test_cases :
241
271
self .assertIsNone (intersection (ll1 , ll2 ), msg = (ll1 , ll2 ))
242
272
273
+ def test_intersection_linear_runtime (self ):
274
+ for ll1 , ll2 , shared_node in self .intersection_test_cases :
275
+ result_node = intersection_linear_runtime (ll1 , ll2 )
276
+ self .assertTrue (result_node is shared_node , msg = (ll1 , ll2 , shared_node ))
277
+
278
+ for ll1 , ll2 in self .no_intersection_test_cases :
279
+ self .assertIsNone (intersection_linear_runtime (ll1 , ll2 ), msg = (ll1 , ll2 ))
280
+
243
281
244
282
if __name__ == '__main__' :
245
283
unittest .main ()
0 commit comments