In [45]:
class Node:
def __init__(self, val, nxt = None):
self.val = val
self.nxt = nxt
# def FromList(xs):
# # recursively construct a linked list from xs
# last = Node(xs[-1]) # last node in the linked list with no succesor
# nxt = last
# for i in range(len(xs)-1, 0, -1):
# nxt = Node(xs[i], nxt)
# return nxt
def FromList(xs):
if len(xs) == 0:
return None
else:
return Node(xs[0], Node.FromList(xs[1:]))
def getVal(self, n):
if n == 0:
return self.val
if self.nxt == None:
return None
return self.nxt.getVal(n-1)
def getNode(self,n):
if n == 0:
return self
if self.nxt == None:
return None
return self.nxt.getNode(n-1)
In [46]:
example1 = Node.FromList([3,4,5,6,7,8,9])
example2 = Node.FromList([3,4,5,6,7,8,9])
example2.getNode(6).nxt = example2 # cycle: last points to first
example3 = Node.FromList([3,4,5,6,7,8,9])
example3.getNode(6).nxt = example3.getNode(4) # cycle: last points to 5th
In [47]:
[example1.getVal(i) for i in range(7)] # should be 3,4,5,6,7,8,9
Out[47]:
[3, 4, 5, 6, 7, 8, 9]
In [48]:
[example2.getVal(i) for i in range(10)] # should be 3,4,5,6,7,8,9,3,4,5
Out[48]:
[3, 4, 5, 6, 7, 8, 9, 3, 4, 5]
In [49]:
def find_cycles_bigspace(node):
# do the O(n) space complexity thing
seen = {node} # set of nodes that were already visited
while node.nxt != None: # node is not the last one
if node.nxt in seen: # O(1) time
return node # found a node in cycle
else:
seen.add(node)
node = node.nxt
return None # no node in cycle because no cycles
In [50]:
for eg in [example1,example2,example3]:
print(find_cycles_bigspace(eg))
None <__main__.Node object at 0x10873c160> <__main__.Node object at 0x1086a20d0>
In [51]:
def find_cycles_const(node):
# O(1) space complexity
prev = node
length = 1 # ruled out cycles shorter or equal to this by steady state
while node.nxt != None: # node is not the last one
for i in range(length):
node = node.nxt
if node == None:
return None
elif node == prev:
return node
i += 1
prev = node
length = 2*length
return None # no node in cycle because no cycles
In [52]:
for eg in [example1,example2,example3]:
print(find_cycles_const(eg))
None <__main__.Node object at 0x1086959b0> <__main__.Node object at 0x1083ee750>
In [ ]: