Given the head of a linked list that may contain a loop. A loop means that the last node of the linked list is connected back to a node in the same list. The task is to find the Starting node ofthe loop in the linked list if there is no loop in the linked list return -1.
Example:
Input:
Output: 3 Explanation: We can see that there exists a loop in the given linked list and the first node of the loop is 3.
Input:
Output: -1 Explanation: No loop exists in the above linked list. So the output is -1.
[Naive approach] Using Hashing - O(n) Time and O(n) Space
The idea is to start traversing the Linked List from head node and while traversing insert each node into the HashSet. If there is a loop present in the Linked List, there will be a node which will be already present in the hash set.
If there is a node which is already present in the HashSet, return the node value which represent the starting node of loop.
else, if there is no node which isalready present in the HashSet , then return -1.
C++
// C++ program to find starting node // of loop using Hasing#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};// Function to detect a loop in the linked list and // return the node where the cycle starts using HashSetNode*findFirstNode(Node*head){// HashSet to store visited nodesunordered_set<Node*>st;Node*currNode=head;// Traverse the linked listwhile(currNode!=nullptr){// If the current node is already in the HashSet,// then this is the starting node of the loopif(st.find(currNode)!=st.end()){returncurrNode;}// If not, add the current node to the HashSetst.insert(currNode);// Move to the next nodecurrNode=currNode->next;}// If no loop found, return nullptrreturnnullptr;}intmain(){// Create a linked list: 10 -> 15 -> 4 -> 20Node*head=newNode(10);head->next=newNode(15);head->next->next=newNode(4);head->next->next->next=newNode(20);head->next->next->next->next=head;Node*loopNode=findFirstNode(head);if(loopNode)cout<<loopNode->data;elsecout<<-1;return0;}
Java
// Java program to find starting node // of loop using Hasingimportjava.util.HashSet;classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}// Function to detect a loop in the linked list and // return the node where the cycle starts using HashSetclassGfG{staticNodefindFirstNode(Nodehead){// HashSet to store visited nodesHashSet<Node>st=newHashSet<>();NodecurrNode=head;// Traverse the linked listwhile(currNode!=null){// If the current node is already in the HashSet,// then this is the starting node of the loopif(st.contains(currNode)){returncurrNode;}// If not, add the current node to the HashSetst.add(currNode);// Move to the next nodecurrNode=currNode.next;}// If no loop found, return nullreturnnull;}publicstaticvoidmain(String[]args){// Create a linked list: 10 -> 15 -> 4 -> 20Nodehead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;NodeloopNode=findFirstNode(head);if(loopNode!=null)System.out.println(loopNode.data);elseSystem.out.println(-1);}}
Python
# Python program to find starting node # of loop using HasingclassNode:def__init__(self,x):self.data=xself.next=None# Function to detect a loop in the linked list and # return the node where the cycle starts using HashSetdeffindFirstNode(head):# HashSet to store visited nodesst=set()currNode=head# Traverse the linked listwhilecurrNodeisnotNone:# If the current node is already in the HashSet,# then this is the starting node of the loopifcurrNodeinst:returncurrNode# If not, add the current node to the HashSetst.add(currNode)# Move to the next nodecurrNode=currNode.next# If no loop found, return NonereturnNoneif__name__=="__main__":# Create a linked list: 10 -> 15 -> 4 -> 20head=Node(10)head.next=Node(15)head.next.next=Node(4)head.next.next.next=Node(20)head.next.next.next.next=headloopNode=findFirstNode(head)ifloopNode:print(loopNode.data)else:print(-1)
C#
// C# program to find starting node // of loop using HasingusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGfG{// Function to detect a loop in the linked list and // return the node where the cycle starts using HashSetstaticNodefindFirstNode(Nodehead){// HashSet to store visited nodesHashSet<Node>st=newHashSet<Node>();NodecurrNode=head;// Traverse the linked listwhile(currNode!=null){// If the current node is already in the HashSet,// then this is the starting node of the loopif(st.Contains(currNode)){returncurrNode;}// If not, add the current node to the HashSetst.Add(currNode);// Move to the next nodecurrNode=currNode.next;}// If no loop found, return nullreturnnull;}staticvoidMain(){// Create a linked list: 10 -> 15 -> 4 -> 20Nodehead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;NodeloopNode=findFirstNode(head);if(loopNode!=null)Console.WriteLine(loopNode.data);elseConsole.WriteLine(-1);}}
JavaScript
// Javascript program to find starting node // of loop using HasingclassNode{constructor(x){this.data=x;this.next=null;}}// Function to detect a loop in the linked list and // return the node where the cycle starts using HashSetfunctionfindFirstNode(head){// HashSet to store visited nodesletst=newSet();letcurrNode=head;// Traverse the linked listwhile(currNode!==null){// If the current node is already in the HashSet,// then this is the starting node of the loopif(st.has(currNode)){returncurrNode;}// If not, add the current node to the HashSetst.add(currNode);// Move to the next nodecurrNode=currNode.next;}// If no loop found, return nullreturnnull;}// Create a linked list: 10 -> 15 -> 4 -> 20lethead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;letloopNode=findFirstNode(head);if(loopNode){console.log(loopNode.data);}else{console.log(-1);}
Output
10
[Expected Approach] Using Floyd's loop detection algorithm - O(n) Time and O(1) Space
This approach can be divided into two parts:
1. Detect Loop in Linked List using Floyd’s Cycle Detection Algorithm:
This idea is to useFloyd’s Cycle-Finding Algorithmtofind a loop in a linked list. It uses two pointers slow and fast, fast pointer movetwo steps ahead andslow will moveone stepahead at a time.
Follow the steps below to solve the problem:
Traverse linked list using two pointers (slow and fast).
Move one pointer(slow) by one step ahead and another pointer(fast) by two steps ahead.
If these pointers meet at the same node then there is a loop. If pointers do not meet then the linked list doesn’t have a loop.
Below is the illustration of above algorithm:
2. Find Starting node of Loop:
After detecting that the loop is present using above algorithm, to find the starting node of loop in linked list, we will reset the slow pointer to head node and fast pointer will remain at its position. Both slow and fast pointers move one step ahead until fast not equals to slow. The meeting point will be the Starting node of loop.
// C++ program to return first node of loop.#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};// Function to detect a loop in the linked list and // return the node where the cycle starts using// Floyd’s Cycle-Finding AlgorithmNode*findFirstNode(Node*head){// Initialize two pointers, slow and fastNode*slow=head;Node*fast=head;// Traverse the listwhile(fast!=nullptr&&fast->next!=nullptr){// Move slow pointer by one stepslow=slow->next;// Move fast pointer by two stepsfast=fast->next->next;// Detect loopif(slow==fast){// Move slow to head, keep fast at meeting pointslow=head;// Move both one step at a time until they meetwhile(slow!=fast){slow=slow->next;fast=fast->next;}// Return the meeting node, which// is the start of the loopreturnslow;}}// No loop foundreturnnullptr;}intmain(){// Create a linked list: 10 -> 15 -> 4 -> 20Node*head=newNode(10);head->next=newNode(15);head->next->next=newNode(4);head->next->next->next=newNode(20);head->next->next->next->next=head;Node*loopNode=findFirstNode(head);if(loopNode)cout<<loopNode->data;elsecout<<-1;return0;}
C
// C++ program to return first node of loop.#include<stdio.h>#include<stdlib.h>structNode{intdata;structNode*next;};// Function to detect a loop in the linked list and // return the node where the cycle starts // using Floyd’s Cycle-Finding AlgorithmstructNode*findFirstNode(structNode*head){structNode*slow=head;structNode*fast=head;// Traverse the listwhile(fast!=NULL&&fast->next!=NULL){// Move slow pointer by one stepslow=slow->next;// Move fast pointer by two stepsfast=fast->next->next;// Detect loopif(slow==fast){// Move slow to head, keep fast at meeting pointslow=head;// Move both one step at a time until they meetwhile(slow!=fast){slow=slow->next;fast=fast->next;}// Return the meeting node, which is the // start of the loopreturnslow;}}// No loop foundreturnNULL;}structNode*createNode(intdata){structNode*newNode=(structNode*)malloc(sizeof(structNode));newNode->data=data;newNode->next=NULL;returnnewNode;}intmain(){// Create a linked list: 10 -> 15 -> 4 -> 20structNode*head=createNode(10);head->next=createNode(15);head->next->next=createNode(4);head->next->next->next=createNode(20);head->next->next->next->next=head;structNode*loopNode=findFirstNode(head);if(loopNode)printf("%d\n",loopNode->data);elseprintf(-1);return0;}
Java
// Java program to return first node of loop.classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}classGfG{// Function to detect a loop in the linked list and // return the node where the cycle starts // using Floyd’s Cycle-Finding AlgorithmstaticNodefindFirstNode(Nodehead){// Initialize two pointers, slow and fastNodeslow=head;Nodefast=head;// Traverse the listwhile(fast!=null&&fast.next!=null){// Move slow pointer by one stepslow=slow.next;// Move fast pointer by two stepsfast=fast.next.next;// Detect loopif(slow==fast){// Move slow to head, keep fast at meeting pointslow=head;// Move both one step at a time until they meetwhile(slow!=fast){slow=slow.next;fast=fast.next;}// Return the meeting node, which is the// start of the loopreturnslow;}}// No loop foundreturnnull;}publicstaticvoidmain(String[]args){// Create a linked list: 10 -> 15 -> 4 -> 20Nodehead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;NodeloopNode=findFirstNode(head);if(loopNode!=null)System.out.println(loopNode.data);elseSystem.out.println(-1);}}
Python
# Python3 program to return first node of loop.classNode:def__init__(self,x):self.data=xself.next=NonedeffindFirstNode(head):# Initialize two pointers, slow and fastslow=headfast=head# Traverse the listwhilefastandfast.next:# Move slow pointer by one stepslow=slow.next# Move fast pointer by two stepsfast=fast.next.next# Detect loopifslow==fast:# Move slow to head, keep# fast at meeting pointslow=head# Move both one step at a time until# they meetwhileslow!=fast:slow=slow.nextfast=fast.next# Return the meeting node, which is the # start of the loopreturnslow# No loop foundreturnNone# Create a linked list: 10 -> 15 -> 4 -> 20head=Node(10)head.next=Node(15)head.next.next=Node(4)head.next.next.next=Node(20)head.next.next.next.next=headloopNode=findFirstNode(head)ifloopNode:print(loopNode.data)else:print(-1)
C#
// C# program to return first node of loop.usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGfG{// Function to detect a loop in the linked list and // return the node where the cycle starts // using Floyd’s Cycle-Finding AlgorithmstaticNodefindFirstNode(Nodehead){// Initialize two pointers, slow and fastNodeslow=head;Nodefast=head;// Traverse the listwhile(fast!=null&&fast.next!=null){// Move slow pointer by one stepslow=slow.next;// Move fast pointer by two stepsfast=fast.next.next;// Detect loopif(slow==fast){// Move slow to head, keep fast at meeting pointslow=head;// Move both one step at a time until they meetwhile(slow!=fast){slow=slow.next;fast=fast.next;}// Return the meeting node, which is the start // of the loopreturnslow;}}// No loop foundreturnnull;}staticvoidMain(){// Create a linked list: 10 -> 15 -> 4 -> 20Nodehead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;NodeloopNode=findFirstNode(head);if(loopNode!=null)Console.WriteLine(loopNode.data);elseConsole.WriteLine(-1);}}
JavaScript
// Javascript program to return// first node of loop.classNode{constructor(x){this.data=x;this.next=null;}}// Function to detect a loop in the linked list and // return the node where the cycle starts // using Floyd’s Cycle-Finding AlgorithmfunctionfindFirstNode(head){letslow=head;letfast=head;// Traverse the listwhile(fast!==null&&fast.next!==null){// Move slow pointer by one stepslow=slow.next;// Move fast pointer by two stepsfast=fast.next.next;// Detect loopif(slow===fast){// Move slow to head, keep fast at meeting pointslow=head;// Move both one step at a time until they meetwhile(slow!==fast){slow=slow.next;fast=fast.next;}// Return the meeting node, which is// the start of the loopreturnslow;}}// No loop foundreturnnull;}// Create a linked list: 10 -> 15 -> 4 -> 20consthead=newNode(10);head.next=newNode(15);head.next.next=newNode(4);head.next.next.next=newNode(20);head.next.next.next.next=head;constloopNode=findFirstNode(head);if(loopNode){console.log(loopNode.data);}else{console.log(-1);}
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.