Detect loop in a linked listGiven a linked list, check if the linked list has loop or not. Below diagram shows a linked list with a loop. Show Recommended: Please solve it on “PRACTICE” first, before moving on to the solution. The following are different ways of doing this. Solution 1: HashingApproach: Traverse the list one by one and keep putting the node addresses in a Hash Table. At any point, if NULL is reached then return false, and if the next of the current nodes points to any of the previously stored nodes in Hash then return true. C++
Java
Python3
C#
Javascript
Output
Loop found
Complexity Analysis:
Solution 2: This problem can be solved without hashmap by modifying the linked list data structure.
C++
Java
Python3
C#
Javascript
Output
Loop found
Complexity Analysis:
Solution 3: Floyd’s Cycle-Finding Algorithm
The below image shows how the detectloop function works in the code: Implementation of Floyd’s Cycle-Finding Algorithm: C++
C
Java
Python
C#
Javascript
Output
Loop found
Complexity Analysis:
How does above algorithm work? Solution 4: Marking visited nodes without modifying the linked list data structure Below is the implementation of the above approach: C++
Java
Python3
C#
Javascript
Output
Loop Found
Complexity Analysis:
Solution 5: Store length In this method, two pointers are created, first (always points to head) and last. Each time the last pointer moves we calculate no of nodes in between first and last and check whether the current no of nodes > previous no of nodes, if yes we proceed by moving last pointer else it means we’ve reached the end of the loop, so we return output accordingly. C++
Java
Python3
C#
Javascript
Output
Loop Found
Complexity Analysis:
Another Approach:
Follow the code given below for a better understanding: C++
Java
Python3
C#
Javascript
Output
1
Time Complexity: O(N) Auxiliary Space: O(1) Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Article Tags :
Linked List
Accolite Amazon Linked Lists loop MAQ Software Samsung Tortoise-Hare-Approach Practice Tags :
Accolite Amazon Samsung MAQ Software Linked List Explanation on finding the starting node of a loop in Linked ListGiven a linked list with loop, consider 2 pointers — one pointer (Slow pointer) moving with speed sand other pointer (Fast pointer) moving with speed 2*s. Given a loop in linked list, these two pointers will definitely meet at a point within loop. Distance traveled by Slow pointer to reach meeting point: D(slow)=x+t1*(y+z)t1: rounds of loop taken by slow pointer till slow and fast pointer meet at a pointD(fast)=x+t2*(y+z)t2 : rounds taken by fast pointer till slow and fast pointer meet at a pointBoth slow and fast pointer takes same amount of time to reach the meeting point. Time taken by slow pointer=Time taken by fast pointer(since Time= Distance/speed)(x+t1*(loop)+y)/s =(x+ t2*(loop)+y)/2s2(x+t1*(loop)+y)= x+t2*(loop)+y2x-x+ (t1-t2)*(loop)+2y-y=0x+ (t1-t2)*(loop)+y=0since loop= y+zx+(t1-t2)*(y+z)+y=0x+(t1-t2+1)*y+(t1-t2)*z=0x=(t2-t1)*z +(t2-t1-1)*y -------(i)Too many equations here, right? Let’s consider an example: Notations( D represents x, K represents y and M represents z) Here, x=8, y=1 and z=2 fast pointer runs in loop for 3 times till it reaches meeting point,hence t2=3 slow pointer reaches the meeting point before completing the loop, hence t1=0 from equation (i) x=(t2-t1)*z +(t2-t1-1)*ywe know, x=8 let’s find the RHS and verify if LHS=RHS? calculating value on RHS: (t2-t1)*z+(t2-t1–1)*y (substituting values: t2=3, t1=0, z=2, y=1) (3-0)*2+(3 -0-1)*1= 3*2+(2)*1 = 8 So, distance from head of linked list = distance from meeting point till both the pointers meet. If we start a pointer from head of the linked list and another one from meeting point then where will they meet? loop: z+y RHS: (t2-t1)*z+(t2-t1–1)*y (considered we are at meeting point) Let’s change the perspective and take y steps back and we’ll reach the starting point of the loop, right? now RHS becomes: (t2-t1)*z+(t2-t1–1)*y+y (considered we are at starting point, and since y distance was already covered by the pointer hence it wasn’t included. But now that we are changing the perspective of the problem and considering it to start from start of the loop we need to add y to the RHS. Simple math) => (t2-t1)*z+(t2-t1)*y => (t2-t1)*(y+z) =>(t2-t1)*(loop) Now this will always end up in the starting position no matter what t2 and t1 is as loop will be completed as whole. and since LHS=RHS (as proved already) So, it can be easily observed that if we start a pointer from head of the linked list and another from meeting point of the linked list, the pointers will cover same distance and meet at starting node of the list. Here’s the implementation of above explained approach in java: public Node detectCycle(Node head) {Node slow=head ,fast=head; while(fast!=null && fast.next!=null && slow.next!=null) { fast=fast.next.next; slow=slow.next; if(fast==slow) break; } if(fast==null || fast.next==null) //if there is no loop return null; else { slow=head; //starting the pointer from head while(slow!=fast) { slow=slow.next; fast=fast.next; } return slow; } } Time complexity is O(n) and Space complexity is O(1) Happy coding and enjoy debugging :) Detect loop in a Linked listA loop in a linked list is a condition that occurs when the linked list does not have any end. When the loop exists in the linked list, the last pointer does not point to the Null as observed in the singly linked list or doubly linked list and to the head of the linked list observed in the circular linked list. When the loop exists, it points to some other node, also known as the linked list cycle. Let's understand the loop through an example. In the above figure, we can observe that the loop exists in the linked list. Here, the problem statement is that we have to detect the node, which is the start of the loop. The solution to solve this problem is:
Detecting a loopFirst, we will detect a loop in the linked list. To understand this, we will look at the algorithm for detecting a loop. Step 1: First, we will initialize two pointers, i.e., S as a slow pointer and F as a fast pointer. Initially, both the pointers point to the first node in the linked list. Step 2: Move the 'S' pointer one node at a time while move the 'F' pointer two nodes at a time. Step 3: If at some point that both the pointers, i.e., 'S' and 'F, point to the same node, then there is a loop in the linked list; otherwise, no loop exists. Let's visualize the above algorithm for more clarity. As we can observe in the above figure that both the pointers, i.e., S and F point to the first node. Now, we will move the 'S' pointer by one and the 'F' pointer by two until they meet. If the 'F' pointer reaches the end node means that there is no loop in the linked list. The 'S' pointer moves by one whereas the 'F' pointer moves by two, so 'S' pointer points to node 1, and the 'F' pointer points to node 9 shown as below: Since both the pointers do not point to the same node and 'F' pointer does not reach the end node so we will again move both the pointers. Now, pointer 'S' will move to the node 9, and pointer 'F' will move to node 2, shown as below: Since both the pointers do not point to the same node, so again, we will increment the pointers. Now, 'S' will point to node 4, and 'F' will point to the node 7 shown as below: Since both the pointers do not point to the same node, so again, we will increment the pointers. Now, 'S' will point to the node 2, and 'F' will point to node 9 shown as below: Since both the pointers do not point to the same node, so again, we will increment the pointers. Now, 'S' will point to node 3, and 'F' will also point to node 3 shown as below: As we can observe in the above figure, both pointers point to the same node, i.e., 3; therefore, the loop exists in the linked list. Detecting start of the loopHere, we need to detect the origination of the loop. We will consider the same example which we discussed in detecting the loop. To detect the start of the loop, consider the below algorithm. Step 1: Move 'S' to the start of the list, but 'F' would remain point to node 3. Step 2: Move 'S' and 'F' forward one node at a time until they meet. Step 3: The node where they meet is the start of the loop. Let's visualize the above algorithm for more clarity. First, we increment the pointer 'S' and 'F' by one; 'S' and 'F' would point to node 1 and node 7, respectively, shown as below: Since both the node are not met, so we again increment the pointers by one node shown as below: As we can observe in the above figure that the 'S' pointer points to node 9 and 'F' pointer points to the node 2. So again, we increment both the pointers by one node. Now, 'S' would point to the node 4, and 'F' would point to the node 9, shown as below: As we can observe in the above figure that both the pointers do not point to the same node, so again, we will increment both the pointers by one node. Now, pointer 'S' and 'F' point to node 2 shown as below: Since both the pointers point to the same node, i.e., 2; therefore, we conclude that the starting node of the loop is node 2. Why this algorithm works? Consider 'l' that denotes the length of the loop, which will measure the number in the links. L: length of the loop As we can observe in the above figure that there are five links. Consider 'm' as the distance of the start of the loop from the beginning of the list. In other words, 'm' can be defined as the distance from the starting node to the node from where the loop gets started. So, in the above figure, m is 4 because the starting node is 8 and the node from the loop gets started is 2. Consider 'k' is the distance of the meeting point of 'S' and 'F' from the start of the loop when they meet for the first time while detecting the loop. In the above linked list, the value of 'k' would be 1 because the node where both fast and slow pointers meet the first time is 3, and the node from where the loop has been started is 2. When 'S' and 'F' meet for the first time then, Let's assume that the total distance covered by the slow pointer is distance_S, and the total distance covered by the fast pointer is distance_F. distance_S = m + p*l + k where the total distance covered by S is the sum of the distance from the beginning of the list to the start of the loop, the distance covered by the slow pointer in the loop, and the distance from the start of the loop to the node where both the pointers meet. distance_F = m + q*l + k (q>p since the speed of 'S' is greater than the speed of 'F') As we know that when 'S' and 'F' met the first time, then 'F' traverses twice as faster as the 'S' pointer; therefore, the distance covered by 'F' would be two times the distance covered by 'S'. Mathematically, it can be represented as: distance_F = 2distance_S The above equation can be written as: m + q*l + k = 2(m + p*l + k) Solving the above equation, we would get: m+k = (q-2p)*l, which implies that m+k is an integer multiple of l (length of the loop). Implementation of detecting loop in C. In the above code, detectloop() is the name of the function which will detect the loop in the linked list. We have passed the list pointer of type struct node pointing to the head node in the linked list. Inside the detectloop() function, we have declared two pointers, i.e., 'S' and 'F' of type struct node and assign the reference of the head node to these pointers. We define the while loop in which we are checking whether the 'S', 'F' and F->next are NULL or not. If they are not Null, then the control will go inside the while loop. Within the while loop, 'S' pointer is incremented by one node and 'F' pointer is incremented by two. If both 'F' and 'S' gets equal; means that the loop exists in the linked list. Next TopicInorder Traversal ← prev next → |