More
    AlgorithmsFloyd's Cycle Detection Algorithm

    Floyd’s Cycle Detection Algorithm

    Floyd’s Cycle Detection Algorithm or the Hare-Tortoise Algorithm is a two pointer approach based algorithm. It is most commonly used in finding loop in a linked list, but it can also be used in solving the problems where we are required to find the number which is repeating in an array of N numbers, in O(N) time complexity.

    It uses two pointers, out of which, one is slow, which moves 1 position, and the other is fast, which moves 2 positions at a time.

    How does Floyd’s Cycle Detection Algorithm Works?

    While traversing the linked list one of these things will occur:

    • The Fast pointer may reach the end (null) this shows that there is no loop n the linked list.
    • The Fast pointer again catches the slow pointer at some time during the iteration, therefore a loop exists in the linked list (or an array).

    Pseudocode:

    • Initialize two-pointers and start traversing the linked list.
    • Move the slow pointer by one position.
    • Move the fast pointer by two positions.
    • If both pointers meet at some point then a loop exists and if the fast pointer meets the end (null) position then no loop exists.

    Below is the implementation for the Floyd’s Cycle Detection Algorithm:


    In C++:

    
    #include <bits/stdc++.h>
    using namespace std;
    
    class Node {
    public:
    	int data;
    	Node* next;
    
    	Node(int data)
    	{
    		this->data = data;
    		next = NULL;
    	}
    };
    
    // initialize a new head for the linked list
    Node* head = NULL;
    class Linkedlist {
    public:
    	// insert new value at the start
    	void insert(int value)
    	{
    		Node* newNode = new Node(value);
    		if (head == NULL)
    			head = newNode;
    		else {
    			newNode->next = head;
    			head = newNode;
    		}
    	}
    
    	// detect if there is a loop
    	// in the linked list
    	bool detectLoop()
    	{
    		Node *slowPointer = head,
    			*fastPointer = head;
    
    		while (slowPointer != NULL
    			&& fastPointer != NULL
    			&& fastPointer->next != NULL) {
    			slowPointer = slowPointer->next;
    			fastPointer = fastPointer->next->next;
    			if (slowPointer == fastPointer)
    				return 1;
    		}
    
    		return 0;
    	}
    };
    
    int main()
    {
    	Linkedlist l1;
    	// inserting new values
    	l1.insert(10);
    	l1.insert(20);
    	l1.insert(30);
    	l1.insert(40);
    	l1.insert(50);
    
    	// adding a loop for the sake
    	// of this example
    	Node* temp = head;
    	while (temp->next != NULL)
    		temp = temp->next;
    
    	temp->next = head;
    
    	// loop added;
    
    	if (l1.detectLoop())
    		cout << "Loop exists in the"
    			<< " Linked List" << endl;
    	else
    		cout << "Loop does not exists "
    			<< "in the Linked List" << endl;
    
    	return 0;
    }
    

    Output

    Loop exists in the Linked List

    In Java:

    import java.util.*;
    
    class Solution{
    
    static class Node {
    	int data;
    	Node next;
    
    	Node(int data)
    	{
    		this.data = data;
    		next = null;
    	}
    };
    static Node head = null;
    static class Linkedlist {
    	void insert(int value)
    	{
    		Node newNode = new Node(value);
    		if (head == null)
    			head = newNode;
    		else {
    			newNode.next = head;
    			head = newNode;
    		}
    	}
    
    
    	boolean detectLoop()
    	{
    		Node slowPointer = head,
    			fastPointer = head;
    
    		while (slowPointer != null
    			&& fastPointer != null
    			&& fastPointer.next != null) {
    			slowPointer = slowPointer.next;
    			fastPointer = fastPointer.next.next;
    			if (slowPointer == fastPointer)
    				return true;
    		}
    
    	return false;
    	}
    }
    
    public static void main(String[] args)
    {
    	Linkedlist l1 = new Linkedlist();
    	// inserting new values
    	l1.insert(10);
    	l1.insert(20);
    	l1.insert(30);
    	l1.insert(40);
    	l1.insert(50);
    	Node temp = head;
    	while (temp.next != null)
    		temp = temp.next;
    
    	temp.next = head;
    
    	// loop added;
    
    	if (l1.detectLoop())
    		System.out.print("Loop exists in the"
    			+ " Linked List" +"\n");
    	else
    		System.out.print("Loop does not exists "
    			+ "in the Linked List" +"\n");
    
    }
    }
    

    Output

    Loop exists in the Linked List

    Time Complexity is O(N) as we have traversed the list only once. The space complexity is O(1), i.e., constant space is used to initialize two pointers.

    We have a mathematical proof for, why does Floyd’s Cycle Detection Algorithm works. We won’t go that way for proving that. You can check out this if you are interested.

    Mathematical proof of Floyd’s Cycle Detection Algorithm

    Some problems also require us to determine the point where the cycle starts in a linked list.

    We need to reset the slow pointer to the head (or starting point of the linked list) and again move the slow and fast pointer, but, this time, 1 position at a time for slow as well as fast pointer.

    If you have read the mathematical proof given in the link above, you might have observed that they both will meet again at a point which is the starting point of the cycle.

    Below is the implementation for the same:


    In C++:

    #include <bits/stdc++.h>
    using namespace std;
    
    class Node {
    public:
    	int data;
    	Node* next;
    
    	Node(int data)
    	{
    		this->data = data;
    		next = NULL;
    	}
    };
    Node* head = NULL;
    class Linkedlist {
    public:
    	// insert new value at the start
    	void insert(int value)
    	{
    		Node* newNode = new Node(value);
    		if (head == NULL)
    			head = newNode;
    		else {
    			newNode->next = head;
    			head = newNode;
    		}
    	}
    
    	// detect if there is a loop
    	// in the linked list
    	Node* detectLoop()
    	{
    		Node *slowPointer = head,
    			*fastPointer = head;
    
    		while (slowPointer != NULL
    			&& fastPointer != NULL
    			&& fastPointer->next != NULL) {
    			slowPointer = slowPointer->next;
    			fastPointer = fastPointer->next->next;
    			if (slowPointer == fastPointer)
    				break;
    		}
    
    		// if no loop exists
    		if (slowPointer != fastPointer)
    			return NULL;
    
    		// reset slow pointer to head
    		// and traverse again
    		slowPointer = head;
    		while (slowPointer != fastPointer) {
    			slowPointer = slowPointer->next;
    			fastPointer = fastPointer->next;
    		}
    
    		return slowPointer;
    	}
    };
    
    int main()
    {
    	Linkedlist l1;
    	// inserting new values
    	l1.insert(10);
    	l1.insert(20);
    	l1.insert(30);
    	l1.insert(40);
    	l1.insert(50);
    
    	Node* temp = head;
    	while (temp->next != NULL)
    		temp = temp->next;
    	// loop added;
    	temp->next = head;
    
    	Node* loopStart = l1.detectLoop();
    	if (loopStart == NULL)
    		cout << "Loop does not exists" << endl;
    	else {
    		cout << "Loop does exists and starts from "
    			<< loopStart->data << endl;
    	}
    
    	return 0;
    }
    

    Output

    Loop does exists and starts from 50

    In Java:

    import java.util.*;
    public class Solution{
    
    static class Node {
    	int data;
    	Node next;
    
    	Node(int data)
    	{
    	this.data = data;
    	next = null;
    	}
    }
    static Node head = null;
    static class Linkedlist {
    
    	void insert(int value)
    	{
    	Node newNode = new Node(value);
    	if (head == null)
    		head = newNode;
    	else {
    		newNode.next = head;
    		head = newNode;
    	}
    	}
    
    	// detect if there is a loop
    	// in the linked list
    	public Node detectLoop()
    	{
    	Node slowPointer = head,
    	fastPointer = head;
    
    	while (slowPointer != null
    			&& fastPointer != null
    			&& fastPointer.next != null) {
    		slowPointer = slowPointer.next;
    		fastPointer = fastPointer.next.next;
    		if (slowPointer == fastPointer)
    		break;
    	}
    
    	// if no loop exists
    	if (slowPointer != fastPointer)
    		return null;
    
    	// reset slow pointer to head
    	// and traverse again
    	slowPointer = head;
    	while (slowPointer != fastPointer) {
    		slowPointer = slowPointer.next;
    		fastPointer = fastPointer.next;
    	}
    
    	return slowPointer;
    	}
    }
    
    public static void main(String[] args)
    {
    	Linkedlist l1 = new Linkedlist();
    	// inserting new values
    	l1.insert(10);
    	l1.insert(20);
    	l1.insert(30);
    	l1.insert(40);
    	l1.insert(50);
    
    	// adding a loop for the sake
    	// of this example
    
    	Node temp = head;
    	while (temp.next != null)
    	temp = temp.next;
    
    	temp.next = head;
    
    	// loop added;
    
    	Node loopStart = l1.detectLoop();
    	if (loopStart == null)
    	System.out.println("Loop does not exists" );
    	else {
    	System.out.println("Loop does exists and starts from "
    						+ loopStart.data);
    	}
    
    }
    }

    Output

    Loop does exists and starts from 50

    That’s all for the linked list but how to solve the problems like,

    Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.

    There is only one repeated number in nums, and we have to find that repeated number.

    We are also given with the instruction that we must solve the problem without modifying the array nums and uses only constant extra space.

    Practice the problem here

    Here comes the Floyd’s Cycle Detection Algorithm handy.

    Here’s a pseudo code for this problem:

    class Solution:
        def findDuplicate(self, nums: List[int]) -> int:
            fast,slow=0,0
            while True:
                slow=nums[slow]
                fast=nums[nums[fast]]
                if slow==fast:
                    break
            slow2=0
            while True:
                slow=nums[slow]
                slow2=nums[slow2]
                if slow==slow2:
                    return slow
    • This problem states that we have to find the duplicate number in the list without using extra space but we are given that there are numbers ranging from [1,n] and there are n+1 number in the list ,We could actually use this fact as an advantage.
    • So first we have to know this can be seen as a linked list problem where each number in a list is the pointer to the next one. This can be seen in below illustration
    index=[0,1,2,3,4]
    nums=[1,3,4,2,2]
    * You could see that the first element in the list is 1 which means the next element will be at index 1 which is 3 .Now the number is 3 and so the next number will be at index 3 which is number 2,now we will see index 2 which is a 4 and at index 4 there is 2 and now we see that there are two ways to go to index 2 one is from index 3 and other is at index 4.

    Sponsored

    LEAVE A REPLY

    Please enter your comment!
    Please enter your name here

    Subscribe Today

    GET EXCLUSIVE FULL ACCESS TO PREMIUM CONTENT

    Get unlimited access to our EXCLUSIVE Content and our archive of subscriber stories.

    Exclusive content

    Latest article

    More article