From 6502708b29090426f7a4d38ac998cb52d8c661c7 Mon Sep 17 00:00:00 2001 From: Saad Date: Sat, 28 Apr 2018 23:08:03 -0500 Subject: [PATCH 1/2] Add algorithm for finding the starting node in a circular linked list. --- linkedlist/find_loop.py | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 linkedlist/find_loop.py diff --git a/linkedlist/find_loop.py b/linkedlist/find_loop.py new file mode 100644 index 000000000..5378ed2c0 --- /dev/null +++ b/linkedlist/find_loop.py @@ -0,0 +1,68 @@ +""" +Find the start of a linked list loop + +Some constraints: +* It is gonna be a singly linked list. +* The parameter is not always gonna be a circular linked list. +* Once the loop is found, return the node. + +Test Cases: +* Empty list -> None +* Not a circular linked list -> None + * One element + * Two or more elements +* Circular linked list general case +""" +class LinkedList: + + def __init__(self): + self.root = None + + # Function to insert a new node at the beginning + def push(self, new_data): + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node + + def find_loop_start(self): + if self.root is None or self.root.next is None: + return None + + # Detect loop using Floyd’s Cycle detection algorithm + slow = fast = self.root + while fast.root is not None: + slow = slow.next + fast = fast.next.next + + if fast is None: + return None + + if fast == slow: + break + + # check for the starting node + slow = self.root + while slow != fast: + slow = slow.next + fast = fast.next + + if fast is None: + return None + return slow + +class Node: + + def __init__(self, _value): + self.value = _value + self.next = None + + +linked_list = LinkedList() +linked_list.push(10) +linked_list.push(4) +linked_list.push(15) +linked_list.push(20) +linked_list.push(50) + +# Make it a circular linked list +linked_list.root.next.next.next.next.next = linked_list.root.next.next From 282242192fb11c31aa0e4d6c9439ce0b358e4429 Mon Sep 17 00:00:00 2001 From: Sa'd Date: Sat, 28 Apr 2018 23:13:55 -0500 Subject: [PATCH 2/2] Fix indentation error --- linkedlist/find_loop.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linkedlist/find_loop.py b/linkedlist/find_loop.py index 5378ed2c0..d436ebe60 100644 --- a/linkedlist/find_loop.py +++ b/linkedlist/find_loop.py @@ -19,10 +19,10 @@ def __init__(self): self.root = None # Function to insert a new node at the beginning - def push(self, new_data): - new_node = Node(new_data) - new_node.next = self.head - self.head = new_node + def push(self, new_data): + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node def find_loop_start(self): if self.root is None or self.root.next is None: