diff options
author | William Carroll <wpcarro@gmail.com> | 2020-11-21T14·47+0000 |
---|---|---|
committer | William Carroll <wpcarro@gmail.com> | 2020-11-21T14·47+0000 |
commit | 70e74a4027a762180840ec79ccec9c8f998a7683 (patch) | |
tree | 1235f29af42579806cf2470ef98e93c3ed47e099 /scratch/facebook/interview-cake/linked-list-cycles.py | |
parent | cbdac306433dec51c99cc0b363dcfd8d063f78c3 (diff) |
Solve "linked-list-cycles"
Write a predicate for checking if a linked-list contains a cycle. For additional practice, I also implemented a function that accepts a linked-list containing a cycle and returns the first element of that cycle.
Diffstat (limited to 'scratch/facebook/interview-cake/linked-list-cycles.py')
-rw-r--r-- | scratch/facebook/interview-cake/linked-list-cycles.py | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/scratch/facebook/interview-cake/linked-list-cycles.py b/scratch/facebook/interview-cake/linked-list-cycles.py new file mode 100644 index 000000000000..523ecd959daf --- /dev/null +++ b/scratch/facebook/interview-cake/linked-list-cycles.py @@ -0,0 +1,70 @@ +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)) |