tvl-depot/users/wpcarro/scratch/facebook/interview-cake/linked-list-cycles.py
Vincent Ambo 019f8fd211 subtree(users/wpcarro): docking briefcase at '24f5a642'
git-subtree-dir: users/wpcarro
git-subtree-mainline: 464bbcb15c
git-subtree-split: 24f5a642af
Change-Id: I6105b3762b79126b3488359c95978cadb3efa789
2021-12-14 02:15:47 +03:00

70 lines
1.5 KiB
Python

def contains_cycle(node):
"""
Return True if the linked-list, `node`, contains a cycle.
"""
if not node:
return False
a = node
b = node.next
while a != b:
a = a.next
if b and b.next and b.next.next:
b = b.next.next
else:
return False
return True
################################################################################
# Bonus
################################################################################
def first_node_in_cycle(node):
"""
Given that the linked-list, `node`, contains a cycle, return the first
element of that cycle.
"""
# enter the cycle
a = node
b = node.next
while a != b:
a = a.next
b = b.next.next
# get the length of the cycle
beg = a
a = a.next
n = 1
while a != beg:
a = a.next
n += 1
# run b n-steps ahead of a
a = node
b = node
for _ in range(n):
b = b.next
# where they intersect is the answer
while a != b:
a = a.next
b = b.next
return a
################################################################################
# Tests
################################################################################
class Node(object):
def __init__(self, value, next=None):
self.value = value
self.next = next
def __repr__(self):
return "Node({}) -> ...".format(self.value)
d = Node('d')
c = Node('c', d)
b = Node('b', c)
a = Node('a', b)
d.next = b
print(first_node_in_cycle(a))