Find first node of loop in a linked list

22 Jun, 2022
Write a function findFirstLoopNode() that checks whether a given Linked List contains a loop. If the loop is present then it returns point to the first node of the loop. Else it returns NULL.
Example : 
Input : Head of below linked list
Output : Pointer to node 2
We have discussed Floyd’s loop detection algorithm. Below are steps to find the first node of the loop.1. If a loop is found, initialize a slow pointer to head, let fast pointer be at its position. 2. Move both slow and fast pointers one node at a time. 3. The point at which they meet is the start of the loop.
C++
C
Java
Python3
C#
Javascript
// C++ program to return first node of loop.#include <bits/stdc++.h>using namespace std; struct Node {    int key;    struct Node* next;}; Node* newNode(int key){    Node* temp = new Node;    temp->key = key;    temp->next = NULL;    return temp;} // A utility function to print a linked listvoid printList(Node* head){    while (head != NULL) {        cout << head->key << " ";        head = head->next;    }    cout << endl;} // Function to detect and remove loop// in a linked list that may contain loopNode* detectAndRemoveLoop(Node* head){    // If list is empty or has only one node    // without loop    if (head == NULL || head->next == NULL)        return NULL;     Node *slow = head, *fast = head;    // Move slow and fast 1 and 2 steps    // ahead respectively.    slow = slow->next;    fast = fast->next->next;    // Search for loop using slow and    // fast pointers    while (fast && fast->next) {        if (slow == fast)            break;        slow = slow->next;        fast = fast->next->next;    }    // If loop does not exist    if (slow != fast)        return NULL;    // If loop exists. Start slow from    // head and fast from meeting point.    slow = head;    while (slow != fast) {        slow = slow->next;        fast = fast->next;    }    return slow;} /* Driver program to test above function*/int main(){    Node* head = newNode(50);    head->next = newNode(20);    head->next->next = newNode(15);    head->next->next->next = newNode(4);    head->next->next->next->next = newNode(10);     /* Create a loop for testing */    head->next->next->next->next->next = head->next->next;     Node* res = detectAndRemoveLoop(head);    if (res == NULL)        cout << "Loop does not exist";    else        cout << "Loop starting node is " << res->key;    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// C++ program to return first node of loop.#include <stdio.h>#include <stdlib.h> typedef struct Node {    int key;    struct Node* next;} Node; Node* newNode(int key){    Node* temp = (Node*)malloc(sizeof(Node));    temp->key = key;    temp->next = NULL;    return temp;} // A utility function to print a linked listvoid printList(Node* head){    while (head != NULL) {        printf("%d  ",head->key);        head = head->next;    }    printf("/n");} // Function to detect and remove loop// in a linked list that may contain loopNode* detectAndRemoveLoop(Node* head){    // If list is empty or has only one node    // without loop    if (head == NULL || head->next == NULL)        return NULL;     Node *slow = head, *fast = head;     // Move slow and fast 1 and 2 steps    // ahead respectively.    slow = slow->next;    fast = fast->next->next;     // Search for loop using slow and    // fast pointers    while (fast && fast->next) {        if (slow == fast)            break;        slow = slow->next;        fast = fast->next->next;    }     // If loop does not exist    if (slow != fast)        return NULL;     // If loop exists. Start slow from    // head and fast from meeting point.    slow = head;    while (slow != fast) {        slow = slow->next;        fast = fast->next;    }     return slow;} /* Driver program to test above function*/int main(){    Node* head = newNode(50);    head->next = newNode(20);    head->next->next = newNode(15);    head->next->next->next = newNode(4);    head->next->next->next->next = newNode(10);     /* Create a loop for testing */    head->next->next->next->next->next = head->next->next;     Node* res = detectAndRemoveLoop(head);    if (res == NULL)        printf("Loop does not exist");    else        printf("Loop starting node is %d ",res->key);     return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Java program to return// first node of loop.import java.util.*;class GFG{ static class Node{  int key;  Node next;}; static Node newNode(int key){  Node temp = new Node();  temp.key = key;  temp.next = null;  return temp;} // A utility function to// print a linked liststatic void printList(Node head){  while (head != null)  {    System.out.print(head.key + " ");    head = head.next;  }  System.out.println();} // Function to detect and remove loop// in a linked list that may contain loopstatic Node detectAndRemoveLoop(Node head){  // If list is empty or has  // only one node without loop  if (head == null || head.next == null)    return null;   Node slow = head, fast = head;   // Move slow and fast 1  // and 2 steps ahead  // respectively.  slow = slow.next;  fast = fast.next.next;   // Search for loop using  // slow and fast pointers  while (fast != null &&         fast.next != null)  {    if (slow == fast)      break;    slow = slow.next;    fast = fast.next.next;  }   // If loop does not exist  if (slow != fast)    return null;   // If loop exists. Start slow from  // head and fast from meeting point.  slow = head;  while (slow != fast)  {    slow = slow.next;    fast = fast.next;  }   return slow;} // Driver codepublic static void main(String[] args){  Node head = newNode(50);  head.next = newNode(20);  head.next.next = newNode(15);  head.next.next.next = newNode(4);  head.next.next.next.next = newNode(10);   // Create a loop for testing  head.next.next.next.next.next = head.next.next;   Node res = detectAndRemoveLoop(head);  if (res == null)    System.out.print("Loop does not exist");  else    System.out.print("Loop starting node is " +  res.key);}} // This code is contributed by shikhasingrajput
# Python3 program to return first node of loop.class Node:         def __init__(self, key):                 self.key = key        self.next = None  def newNode(key):     temp = Node(key)    return temp # A utility function to print a linked listdef printList(head):         while (head != None):        print(head.key, end = ' ')        head = head.next         print()     # Function to detect and remove loop# in a linked list that may contain loopdef detectAndRemoveLoop(head):         # If list is empty or has only one node    # without loop    if (head == None or head.next == None):        return None      slow = head    fast = head      # Move slow and fast 1 and 2 steps    # ahead respectively.    slow = slow.next    fast = fast.next.next      # Search for loop using slow and    # fast pointers    while (fast and fast.next):        if (slow == fast):            break                 slow = slow.next        fast = fast.next.next      # If loop does not exist    if (slow != fast):        return None      # If loop exists. Start slow from    # head and fast from meeting point.    slow = head         while (slow != fast):        slow = slow.next        fast = fast.next      return slow # Driver codeif __name__=='__main__':         head = newNode(50)    head.next = newNode(20)    head.next.next = newNode(15)    head.next.next.next = newNode(4)    head.next.next.next.next = newNode(10)      # Create a loop for testing    head.next.next.next.next.next = head.next.next      res = detectAndRemoveLoop(head)         if (res == None):        print("Loop does not exist")    else:        print("Loop starting node is " +              str(res.key))  # This code is contributed by rutvik_56
// C# program to return// first node of loop.using System;class GFG{ class Node{  public int key;  public Node next;}; static Node newNode(int key){  Node temp = new Node();  temp.key = key;  temp.next = null;  return temp;} // A utility function to// print a linked liststatic void printList(Node head){  while (head != null)  {    Console.Write(head.key + " ");    head = head.next;  }  Console.WriteLine();} // Function to detect and remove loop// in a linked list that may contain loopstatic Node detectAndRemoveLoop(Node head){  // If list is empty or has  // only one node without loop  if (head == null || head.next == null)    return null;   Node slow = head, fast = head;   // Move slow and fast 1  // and 2 steps ahead  // respectively.  slow = slow.next;  fast = fast.next.next;   // Search for loop using  // slow and fast pointers  while (fast != null &&         fast.next != null)  {    if (slow == fast)      break;    slow = slow.next;    fast = fast.next.next;  }   // If loop does not exist  if (slow != fast)    return null;   // If loop exists. Start slow from  // head and fast from meeting point.  slow = head;  while (slow != fast)  {    slow = slow.next;    fast = fast.next;  }   return slow;} // Driver codepublic static void Main(String[] args){  Node head = newNode(50);  head.next = newNode(20);  head.next.next = newNode(15);  head.next.next.next = newNode(4);  head.next.next.next.next = newNode(10);   // Create a loop for testing  head.next.next.next.next.next =                      head.next.next;   Node res = detectAndRemoveLoop(head);     if (res == null)    Console.Write("Loop does not exist");  else    Console.Write("Loop starting node is " +                    res.key);}} // This code is contributed by shikhasingrajput
<script>// Javascript program to return// first node of loop. class Node{    constructor(key)    {        this.key=key;        this.next=null;    }} // A utility function to// print a linked listfunction printList(head){    while (head != null)  {    document.write(head.key + " ");    head = head.next;  }  document.write("<br>");} // Function to detect and remove loop// in a linked list that may contain loopfunction detectAndRemoveLoop(head){    // If list is empty or has  // only one node without loop  if (head == null || head.next == null)    return null;    let slow = head, fast = head;    // Move slow and fast 1  // and 2 steps ahead  // respectively.  slow = slow.next;  fast = fast.next.next;    // Search for loop using  // slow and fast pointers  while (fast != null &&         fast.next != null)  {    if (slow == fast)      break;    slow = slow.next;    fast = fast.next.next;  }    // If loop does not exist  if (slow != fast)    return null;    // If loop exists. Start slow from  // head and fast from meeting point.  slow = head;  while (slow != fast)  {    slow = slow.next;    fast = fast.next;  }    return slow;} // Driver codelet head = new Node(50);  head.next = new Node(20);  head.next.next = new Node(15);  head.next.next.next = new Node(4);  head.next.next.next.next = new Node(10);    // Create a loop for testing  head.next.next.next.next.next = head.next.next;    let res = detectAndRemoveLoop(head);  if (res == null)    document.write("Loop does not exist");  else    document.write("Loop starting node is " +  res.key); // This code is contributed by unknown2108</script>
Loop starting node is 15
 
How does this approach work? Let slow and fast meet at some point after Floyd’s Cycle finding algorithm. The below diagram shows the situation when the cycle is found. 
We can conclude below from the above diagram 
Distance traveled by fast pointer = 2 * (Distance traveled 
                                         by slow pointer)

(m + n*x + k) = 2*(m + n*y + k)

Note that before meeting the point shown above, fast
was moving at twice speed.

x -->  Number of complete cyclic rounds made by 
       fast pointer before they meet first time

y -->  Number of complete cyclic rounds made by 
       slow pointer before they meet first time
From the above equation, we can conclude below 
    m + k = (x-2y)*n

Which means m+k is a multiple of n.
So if we start moving both pointers again at the same speed such that one pointer (say slow) begins from the head node of the linked list and other pointers (say fast) begins from the meeting point. When the slow pointer reaches the beginning of the loop (has made m steps), the fast pointer would have made also moved m steps as they are now moving the same pace. Since m+k is a multiple of n and fast starts from k, they would meet at the beginning. Can they meet before also? No, because the slow pointer enters the cycle first time after m steps.
Method 2: In this method, a temporary node is created. The next pointer of each node that is traversed is made to point to this temporary node. This way we are using the next pointer of a node as a flag to indicate whether the node has been traversed or not. Every node is checked to see if the next is pointing to a temporary node or not. In the case of the first node of the loop, the second time we traverse it this condition will be true, hence we return that node. The code runs in O(n) time complexity and uses constant memory space.
Below is the implementation of the above approach:
C++
C
Java
Python3
C#
Javascript
// C++ program to return first node of loop#include <bits/stdc++.h>using namespace std; struct Node {    int key;    struct Node* next;}; Node* newNode(int key){    Node* temp = new Node;    temp->key = key;    temp->next = NULL;    return temp;} // A utility function to print a linked listvoid printList(Node* head){    while (head != NULL) {        cout << head->key << " ";        head = head->next;    }    cout << endl;} // Function to detect first node of loop// in a linked list that may contain loopNode* detectLoop(Node* head){     // Create a temporary node    Node* temp = new Node;    while (head != NULL) {         // This condition is for the case        // when there is no loop        if (head->next == NULL) {            return NULL;        }         // Check if next is already        // pointing to temp        if (head->next == temp) {            break;        }         // Store the pointer to the next node        // in order to get to it in the next step        Node* nex = head->next;         // Make next point to temp        head->next = temp;         // Get to the next node in the list        head = nex;    }     return head;} /* Driver program to test above function*/int main(){    Node* head = newNode(50);    head->next = newNode(20);    head->next->next = newNode(15);    head->next->next->next = newNode(4);    head->next->next->next->next = newNode(10);     /* Create a loop for testing */    head->next->next->next->next->next = head->next->next;     Node* res = detectLoop(head);    if (res == NULL)        cout << "Loop does not exist";    else        cout << "Loop starting node is " << res->key;     return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// C program to return first node of loop#include <stdio.h>#include <stdlib.h> typedef struct Node {    int key;    struct Node* next;} Node; Node* newNode(int key){    Node* temp = (Node*)malloc(sizeof(Node));    temp->key = key;    temp->next = NULL;    return temp;} // A utility function to print a linked listvoid printList(Node* head){    while (head != NULL) {        printf("%d ", head->key);        head = head->next;    }    printf("\n");} // Function to detect first node of loop// in a linked list that may contain loopNode* detectLoop(Node* head){     // Create a temporary node    Node* temp = (Node *)malloc(sizeof(Node));    while (head != NULL) {        // This condition is for the case when there is no        // loop        if (head->next == NULL)            return NULL;        // Check if next is already pointing to temp        if (head->next == temp)            break;        // Store the pointer to the next node        // in order to get to it in the next step        Node* nex = head->next;        // Make next point to temp        head->next = temp;        // Get to the next node in the list        head = nex;    }    return head;} /* Driver program to test above function*/int main(){    Node* head = newNode(50);    head->next = newNode(20);    head->next->next = newNode(15);    head->next->next->next = newNode(4);    head->next->next->next->next = newNode(10);     /* Create a loop for testing */    head->next->next->next->next->next = head->next->next;     Node* res = detectLoop(head);    if (res == NULL)        printf("Loop does not exist");    else        printf("Loop starting node is %d ", res->key);     return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// Java program to return first node of loopimport java.util.*;class GFG{ static class Node{    int key;    Node next;}; static Node newNode(int key){    Node temp = new Node();    temp.key = key;    temp.next = null;    return temp;} // A utility function to print a linked liststatic void printList(Node head){    while (head != null)    {        System.out.print(head.key + " ");        head = head.next;    }    System.out.println();} // Function to detect first node of loop// in a linked list that may contain loopstatic Node detectLoop(Node head){     // Create a temporary node    Node temp = new Node();    while (head != null)    {         // This condition is for the case        // when there is no loop        if (head.next == null)        {            return null;        }         // Check if next is already        // pointing to temp        if (head.next == temp)        {            break;        }         // Store the pointer to the next node        // in order to get to it in the next step        Node nex = head.next;         // Make next point to temp        head.next = temp;         // Get to the next node in the list        head = nex;    }     return head;} /* Driver program to test above function*/public static void main(String[] args){    Node head = newNode(50);    head.next = newNode(20);    head.next.next = newNode(15);    head.next.next.next = newNode(4);    head.next.next.next.next = newNode(10);     /* Create a loop for testing */    head.next.next.next.next.next = head.next.next;     Node res = detectLoop(head);    if (res == null)        System.out.print("Loop does not exist");    else        System.out.print("Loop starting node is " +                                         res.key); }} // This code is contributed by gauravrajput1
# Python3 program to return first node of loopclass Node:         def __init__(self, x):                 self.key = x        self.next = None # A utility function to print a linked listdef printList(head):         while (head != None):        print(head.key, end = " ")        head = head.next         # Function to detect first node of loop# in a linked list that may contain loopdef detectLoop(head):         # Create a temporary node    temp = Node(-1)         while (head != None):                 # This condition is for the case        # when there is no loop        if (head.next == None):            return None         # Check if next is already        # pointing to temp        if (head.next == temp):            break         # Store the pointer to the next node        # in order to get to it in the next step        nex = head.next         # Make next point to temp        head.next = temp         # Get to the next node in the list        head = nex     return head # Driver codeif __name__ == '__main__':         head = Node(50)    head.next = Node(20)    head.next.next = Node(15)    head.next.next.next = Node(4)    head.next.next.next.next = Node(10)     # Create a loop for testing    head.next.next.next.next.next = head.next.next     res = detectLoop(head)         if (res == None):        print("Loop does not exist")    else:        print("Loop starting node is ", res.key) # This code is contributed by mohit kumar 29
// C# program to return first node of loopusing System; class GFG{ class Node{    public int key;    public Node next;}; static Node newNode(int key){    Node temp = new Node();    temp.key = key;    temp.next = null;    return temp;} // A utility function to print a linked liststatic void printList(Node head){    while (head != null)    {        Console.Write(head.key + " ");        head = head.next;    }    Console.WriteLine();} // Function to detect first node of loop// in a linked list that may contain loopstatic Node detectLoop(Node head){         // Create a temporary node    Node temp = new Node();         while (head != null)    {                 // This condition is for the case        // when there is no loop        if (head.next == null)        {            return null;        }         // Check if next is already        // pointing to temp        if (head.next == temp)        {            break;        }         // Store the pointer to the next node        // in order to get to it in the next step        Node nex = head.next;                 // Make next point to temp        head.next = temp;         // Get to the next node in the list        head = nex;    }    return head;} // Driver codepublic static void Main(String[] args){    Node head = newNode(50);    head.next = newNode(20);    head.next.next = newNode(15);    head.next.next.next = newNode(4);    head.next.next.next.next = newNode(10);     // Create a loop for testing    head.next.next.next.next.next = head.next.next;     Node res = detectLoop(head);         if (res == null)        Console.Write("Loop does not exist");    else        Console.Write("Loop starting node is " +                       res.key);}} // This code is contributed by Amit Katiyar
<script>// javascript program to return first node of loop      class Node {        constructor() {            this.key = 0;            this.next = null;        }    }       function newNode(key) {         temp = new Node();        temp.key = key;        temp.next = null;        return temp;    }     // A utility function to print a linked list    function printList( head) {        while (head != null) {            document.write(head.key + " ");            head = head.next;        }        document.write("<br/>");    }     // Function to detect first node of loop    // in a linked list that may contain loop    function detectLoop( head) {         // Create a temporary node         temp = new Node();        while (head != null) {             // This condition is for the case            // when there is no loop            if (head.next == null) {                return null;            }             // Check if next is already            // pointing to temp            if (head.next == temp) {                break;            }             // Store the pointer to the next node            // in order to get to it in the next step             nex = head.next;             // Make next point to temp            head.next = temp;             // Get to the next node in the list            head = nex;        }         return head;    }     /* Driver program to test above function */              head = newNode(50);        head.next = newNode(20);        head.next.next = newNode(15);        head.next.next.next = newNode(4);        head.next.next.next.next = newNode(10);         /* Create a loop for testing */        head.next.next.next.next.next = head.next.next;          res = detectLoop(head);        if (res == null)            document.write("Loop does not exist");        else            document.write("Loop starting node is " + res.key);  // This code contributed by gauravrajput1</script>
Loop starting node is 15
 
Method 3: We can also use the concept of hashing in order to detect the first node of the loop. The idea is simple just iterate over the entire linked list and store node addresses in a set(C++ STL) one by one, while adding the node address into the set check if it already contains that particular node address if not then add node address to set if it is already present in the set then the current node is the first node of the loop. 
C++14
Java
Python3
C#
Javascript
// The below function take head of Linked List as// input and return Address of first node in// the loop if present else return NULL. /* Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * };*/ListNode* detectCycle(ListNode* A){     // declaring map to store node address    unordered_set<ListNode*> uset;     ListNode *ptr = A;     // Default consider that no cycle is present    while (ptr != NULL) {         // checking if address is already present in map        if (uset.find(ptr) != uset.end())          return ptr;         // if address not present then insert into the set        else            uset.insert(ptr);                 ptr = ptr->next;    }    return NULL;}// This code is contributed by Pankaj_Joshi
// The below function take head of Linked List as// input and return Address of first node in// the loop if present else return NULL.import java.io.*;import java.util.*; class GFG{  static Node detectCycle(Node A)  {     // declaring map to store node address    Set<Node> uset = new HashSet<Node>();    Node = A;     // Default consider that no cycle is present    while (ptr != NULL)    {       // checking if address is already present in map      if(uset.contains(ptr))      {        return ptr;      }       // if address not present then insert into the set      else      {        uset.add(ptr);      }      ptr = ptr.next;    }    return null;  }} // This code is contributed by avanitrachhadiya2155
# The below function take head of Linked List as# input and return Address of first node in# the loop if present else return NULL.  ''' Definition for singly-linked list. * class ListNode: *     def __init__(self, x): *         self.val=x *         self.next=None * '''def detectCycle(A):      # Declaring map to store node    # address    uset = set()      ptr = A      # Default consider that no cycle    # is present    while (ptr != None):          # Checking if address is already        # present in map        if (ptr in uset):          return ptr          # If address not present then        # insert into the set        else:            uset.add(ptr)                  ptr = ptr.next         return None # This code is contributed by pratham76
// The below function take head of Linked List as// input and return Address of first node in// the loop if present else return NULL. using System.Collections.Generic; public class GFG{class Node{    public int key;    public Node next;};  static Node detectCycle(Node A)  {     // declaring map to store node address    HashSet<Node> uset = new HashSet<Node>();    Node ptr = A;     // Default consider that no cycle is present    while (ptr != null)    {       // checking if address is already present in map      if(uset.Contains(ptr))      {        return ptr;      }       // if address not present then insert into the set      else      {        uset.Add(ptr);      }      ptr = ptr.next;    }    return null;  }} // This code is contributed by 29AjayKumar
<script> // The below function take head of Linked List as// input and return Address of first node in// the loop if present else return NULL.         function detectCycle(A)    {        // declaring map to store node address        let uset = new Set();                 let ptr = A;        // Default consider that no cycle is present    while (ptr != NULL)    {        // checking if address is already present in map      if(uset.has(ptr))      {        return ptr;      }        // if address not present then insert into the set      else      {        uset.add(ptr);      }      ptr = ptr.next;    }    return null;    }  // This code is contributed by patel2127 </script>
purnasrivatsa96
HTTPS
nidhi_biet
GauravRajput1
amit143katiyar
shikhasingrajput
mohit kumar 29
rutvik_56
pratham76
avanitrachhadiya2155
patel2127
unknown2108
arorakashish0911
29AjayKumar
adityakumar129
Linked List
Linked List
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
What is Data Structure: Types, Classifications and Applications
Types of Linked List
Circular Singly Linked List | Insertion
Add two numbers represented by linked lists | Set 2
Flattening a Linked List
Real-time application of Data Structures
Insert a node at a specific position in a linked list
Clone a linked list with next and random pointer | Set 1
Swap nodes in a linked list without swapping data