Open In App

How does Floyd’s slow and fast pointers approach work?

Last Updated : 11 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

We have discussed Floyd’s fast and slow pointer algorithms in Detect loop in a linked list

 The algorithm is to start two pointers, slow and fast from head of linked list. We move slow one node at a time and fast two nodes at a time. If there is a loop, then they will definitely meet. This approach works because of the following facts. 1) When slow pointer enters the loop, the fast pointer must be inside the loop. 

Let fast pointer be distance k from slow. 2) Now if consider movements of slow and fast pointers, we can notice that distance between them (from slow to fast) increase by one after every iteration. After one iteration (of slow = next of slow and fast = next of next of fast), distance between slow and fast becomes k+1, after two iterations, k+2, and so on. When distance becomes n, they meet because they are moving in a cycle of length n. For example, we can see in below diagram, initial distance is 2. After one iteration, distance becomes 3, after 2 iterations, it becomes 4. After 3 iterations, it becomes 5 which is distance 0. And they meet. 

Alternate Proof:

  • Let us give index to all the nodes of the loop starting from 0

Index is assigned to each node of the loop

  • Let the length of the Loop be L
  • Let us observe the movement of the Slow pointer from the beginning of the loop along with iterations.

Iteration

i

Index of the node pointed by 

Slow pointer

1

1

2

2

3

3

4

4

L-1

L-1

L

0

L+1

1

and so on…

From the table , we can say that

Index of the node pointed by Slow pointer after iteration i = i mod L

  • Let us observe the movement of Fast pointer from the beginning of the loop along with iterations.

Iteration

i

Index of the node pointed by

Fast pointer

1

2

2

4

3

6

4

8

(L-1)/2 , if L is odd

(L-2)/2 , if L is even

L-1 , if L is odd

L-2 , if L is even

((L-1)/2)+1 , if L is odd

((L-2)/2)+1 , if L is even

1 , if L is odd

0 , if L is even

and so on…

From the table, we can say that 

Index of the node pointed by Fast pointer after iteration i = ( 2 x i ) mod L

  • One thing to note is that , by the time slow pointer reaches the beginning of the loop , the fast pointer will be d nodes away from the beginning of the loop
  • 0 <= d <= L-1

By the time slow pointer reaches the beginning of the loop, fast pointer is d nodes away from the beginning of the loop

  • Hence for all the consequent iterations too , the Fast pointer will be d nodes away from the node that it would point if it started from beginning of the loop
  • Hence we have
    Index of the node pointed by Fast pointer after iteration i = ( ( 2 x i ) + d ) mod L

Now we have both the equations :

  • Index of the node pointed by Slow pointer after iteration i = i mod L
  • Index of the node pointed by Fast pointer after iteration i = ( ( 2 x i ) + d ) mod L

Now assign i = c , where c = L – d

L – Length of the loop

d – distance between the Fast pointer and beginning of the loop , when Slow pointer reaches the beginning of the loop

Since 0 <= d <= L-1 , implies  1 <= c <= L

  • Index of the node pointed by Slow pointer after iteration i  = i mod L
                                                                                                   = c mod L
                                                                                                   = 0 , ( if c = L )
                                                                                                       c , ( if c < L )
  • Index of the node pointed by Fast pointer after iteration i   = ( ( 2 x i ) + d ) mod L
                                                                                                   = ( ( 2 x c ) + d ) mod L
                                                                                                   = ( 2c + d ) mod L
                                                                                                   = ( c + c + d ) mod L
                                                                                                   = ( c + L ) mod L  , Since c = L – d , implies c + d = L
                                                                                                   = c mod L
                                                                                                   = 0 , ( if c = L )
                                                                                                      c , ( if c < L )
  • Now Both the Slow pointer and the Fast pointer are pointing to the same node
  • Hence proved

 How does cycle removal algorithm work? Please see method 3 of Detect and Remove Loop in a Linked List

Implementation:

Java




// Java program to detect loop in a linked list
class LinkedList {
    Node head; // head of list
  
    /* Linked list Node*/
    class Node {
        int data;
        Node next;
        Node(int d)
        {
            data = d;
            next = null;
        }
    }
  
    /* Inserts a new Node at front of the list. */
    public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                Put in the data*/
        Node new_node = new Node(new_data);
  
        /* 3. Make next of new Node as head */
        new_node.next = head;
  
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
  
    void detectLoop()
    {
        Node slow_p = head, fast_p = head;
        int flag = 0;
        while (slow_p != null && fast_p != null
            && fast_p.next != null) {
            slow_p = slow_p.next;
            fast_p = fast_p.next.next;
            if (slow_p == fast_p) {
                flag = 1;
                break;
            }
        }
        if (flag == 1)
            System.out.println("Loop found");
        else
            System.out.println("Loop not found");
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        LinkedList llist = new LinkedList();
  
        llist.push(20);
        llist.push(4);
        llist.push(15);
        llist.push(10);
  
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head;
  
        llist.detectLoop();
    }
}


C++




// C++ program to detect loop in a linked list
#include <bits/stdc++.h>
using namespace std;
  
/* Link list node */
class Node {
public:
    int data;
    Node* next;
};
  
void push(Node** head_ref, int new_data)
{
    /* allocate node */
    Node* new_node = new Node();
  
    /* put in the data */
    new_node->data = new_data;
  
    /* link the old list of the new node */
    new_node->next = (*head_ref);
  
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
  
int detectLoop(Node* list)
{
    Node *slow_p = list, *fast_p = list;
  
    while (slow_p && fast_p && fast_p->next) {
        slow_p = slow_p->next;
        fast_p = fast_p->next->next;
        if (slow_p == fast_p) {
            return 1;
        }
    }
    return 0;
}
  
/* Driver code*/
int main()
{
    /* Start with the empty list */
    Node* head = NULL;
  
    push(&head, 20);
    push(&head, 4);
    push(&head, 15);
    push(&head, 10);
  
    /* Create a loop for testing */
    head->next->next->next->next = head;
    if (detectLoop(head))
        cout << "Loop found";
    else
        cout << "No Loop";
    return 0;
}


Javascript




<script>
  
// Javascript program to detect loop in a linked list
let head; // head of list
  
/* Linked list Node*/
class Node
{
    constructor(d)
    {
        this.data = d;
        this.next = null;
    }
}
  
/* Inserts a new Node at front of the list. */
function push(new_data)
{
      
    /* 1 & 2: Allocate the Node &
            Put in the data*/
    let new_node = new Node(new_data);
  
    /* 3. Make next of new Node as head */
    new_node.next = head;
  
    /* 4. Move the head to point to new Node */
    head = new_node;
}
  
function detectLoop()
{
    let slow_p = head, fast_p = head;
    let flag = 0;
      
    while (slow_p != null && fast_p != null &&
        fast_p.next != null)
    {
        slow_p = slow_p.next;
        fast_p = fast_p.next.next;
        if (slow_p == fast_p)
        {
            flag = 1;
            break;
        }
    }
    if (flag == 1)
        document.write("Loop found<br>");
    else
        document.write("Loop not found<br>");
}
  
// Driver code
push(20);
push(4);
push(15);
push(10);
  
// Create loop for testing
head.next.next.next.next = head;
  
detectLoop();
  
  
</script>


Python




# Python program to detect loop in the linked list
  
# Node class
  
  
class Node:
  
    # Constructor to initialize the node object
    def __init__(self, data):
        self.data = data
        self.next = None
  
  
class LinkedList:
  
    # Function to initialize head
    def __init__(self):
        self.head = 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
  
    # Utility function to print it the linked LinkedList
    def printList(self):
        temp = self.head
        while(temp):
            print temp.data,
            temp = temp.next
  
    def detectLoop(self):
        slow_p = self.head
        fast_p = self.head
        while(slow_p and fast_p and fast_p.next):
            slow_p = slow_p.next
            fast_p = fast_p.next.next
            if slow_p == fast_p:
                return
  
  
# Driver program for testing
llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(10)
  
# Create a loop for testing
llist.head.next.next.next.next = llist.head
if(llist.detectLoop()):
    print "Found Loop"
else:
    print "No Loop"


C#




// C# program to detect loop in a linked list
using System;
  
public class LinkedList {
    Node head; // head of list
  
    /* Linked list Node*/
    public class Node {
        public int data;
        public Node next;
        public Node(int d)
        {
            data = d;
            next = null;
        }
    }
  
    /* Inserts a new Node at front of the list. */
    public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                Put in the data*/
        Node new_node = new Node(new_data);
  
        /* 3. Make next of new Node as head */
        new_node.next = head;
  
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
  
    Boolean detectLoop()
    {
        Node slow_p = head, fast_p = head;
        while (slow_p != null && fast_p != null
            && fast_p.next != null) {
            slow_p = slow_p.next;
            fast_p = fast_p.next.next;
            if (slow_p == fast_p) {
                return true;
            }
        }
        return false;
    }
  
    /* Driver code */
    public static void Main(String[] args)
    {
        LinkedList llist = new LinkedList();
  
        llist.push(20);
        llist.push(4);
        llist.push(15);
        llist.push(10);
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head;
  
        Boolean found = llist.detectLoop();
        if (found) {
            Console.WriteLine("Loop Found");
        }
        else {
            Console.WriteLine("No Loop");
        }
    }
}


Output

Loop found


Similar Reads

Sort the array using slow sort
Given an array arr[] consisting of N integers, the task is to sort the given array in ascending order using the slow sort. Examples: Input: arr[] = {6, 8, 9, 4, 12, 1}Output: 1 4 6 8 9 12 Input: arr[] = {5, 4, 3, 2, 1}Output: 1 2 3 4 5 Approach: Like Merge Sort, Slow Sort is a Divide and Conquer algorithm. It divides the input array into two halves
7 min read
Slow Start Backoff Algorithm for Ad-Hoc
If the receiver proclaims a large window-size, larger than what the network en-route can manage, then there will always be packet losses. So there will be re-transmissions as well. However, the sender can’t send all the packets for which ACK (Acknowledgement) has not been received. Because of this way, even more congestion in the network will be ca
17 min read
Comparison of Dijkstra’s and Floyd–Warshall algorithms
Dijkstra AlgorithmDijkstra’s Algorithm is a Single-Source Shortest Path SSSP algorithm, i.e., given a source vertex it finds the shortest path from the source to all other vertices. The idea is to generate a SPT (shortest path tree) with a given source as a root and with two sets, one set contains vertices included in the shortest-path tree, other
4 min read
Time and Space Complexity of Floyd Warshall Algorithm
The Floyd Warshall Algorithm has a time complexity of O(V3) and a space complexity of O(V2), where V represents the number of vertices in the graph. This algorithm computes the shortest paths between all pairs of vertices in a weighted graph. The time complexity arises from the triple nested loops used to update the shortest path matrix, while the
3 min read
Program to print Reverse Floyd's triangle
Floyd’s triangle is a triangle with first natural numbers. Task is to print reverse of Floyd’s triangle.Examples: Input : 4 Output : 10 9 8 7 6 5 4 3 2 1 Input : 5 Output : 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 C/C++ Code // CPP program to print reverse of // floyd's triangle #include &lt;bits/stdc++.h&gt; using namespace std; void printReverseFloyd(
3 min read
Floyd-Rivest Algorithm
The Floyd-Rivest algorithm is a selection algorithm used to find the kth smallest element in an array of distinct elements. It is similar to the QuickSelect algorithm but has a better running time in practice. Like QuickSelect, the algorithm works on the idea of partitioning. After partitioning an array, the partition element ends up in the correct
11 min read
Floyd’s Cycle Finding Algorithm
Floyd's cycle finding algorithm or Hare-Tortoise algorithm is a pointer algorithm that uses only two pointers, moving through the sequence at different speeds. This algorithm is used to find a loop in a linked list. It uses two pointers one moving twice as fast as the other one. The faster one is called the fast pointer and the other one is called
14 min read
Finding shortest path between any two nodes using Floyd Warshall Algorithm
Given a graph and two nodes u and v, the task is to print the shortest path between u and v using the Floyd Warshall algorithm. Examples: Input: u = 1, v = 3 Output: 1 -&gt; 2 -&gt; 3 Explanation: Shortest path from 1 to 3 is through vertex 2 with total cost 3. The first edge is 1 -&gt; 2 with cost 2 and the second edge is 2 -&gt; 3 with cost 1. In
13 min read
Program to Print Floyd's Triangle
Floyd's triangle is a triangle with first natural numbers. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Recommended PracticeFloyd\'s triangleTry It! Following program prints Floyd's triangle with n lines. C/C++ Code #include &lt;bits/stdc++.h&gt; using namespace std; void printFloydTriangle(int n) { int i, j, val = 1; for (i = 1; i &lt;= n; i++) { for (j =
3 min read
Transitive closure of a graph using Floyd Warshall Algorithm
Given a directed graph, determine if a vertex j is reachable from another vertex i for all vertex pairs (i, j) in the given graph. Here reachable means that there is a path from vertex i to j. The reach-ability matrix is called the transitive closure of a graph. For example, consider below graph Transitive closure of above graphs is 1 1 1 1 1 1 1 1
12 min read
Article Tags :
Practice Tags :