Detect Cycle in Linked List (original) (raw)
Last Updated : 27 Feb, 2026
Given the head of a singly linked list, determine whether the list contains a cycle. A cycle exists if, while traversing the list through next pointers, you encounter a node that has already been visited instead of eventually reaching nullptr.
**Examples:
**Input: head: 1 -> 3 -> 4 -> 3
**Output: true
**Explanation: The last node of the linked list does not point to NULL; instead, it points to an earlier node in the list, creating a cycle.
**Input: head: 1 -> 8 -> 3 -> 4 -> NULL
**Output: false
**Explanation: The last node of the linked list points to NULL, indicating the end of the list.
Table of Content
- [Naive Approach] Using HashSet - O(n) Time and O(n) Space
- [Expected Approach] Using Floyd's Cycle-Finding Algorithm
[Naive Approach] Using HashSet - O(n) Time and O(n) Space
The idea is to insert the nodes in the Hashset while traversing and whenever a node is encountered that is already present in the hashset (which indicates there's a cycle (loop) in the list) then return true. If the node is NULL, represents the end of Linked List, return false as there is no loop.
C++ `
//Driver Code Starts #include #include using namespace std;
//Driver Code Ends
class Node { public: int data; Node* next; Node(int x) { this->data = x; this->next = nullptr; } };
bool detectLoop(Node* head) { unordered_set<Node*>st;
while (head != nullptr) {
// if this node is already present
// in hashmap it means there is a cycle
if (st.find(head) != st.end())
return true;
// if we are seeing the node for
// the first time, insert it in hash
st.insert(head);
head = head->next;
}
return false;}
//Driver Code Starts
int main() {
Node* head = new Node(1);
head->next = new Node(3);
head->next->next = new Node(4);
head->next->next->next = head->next;
if (detectLoop(head))
cout << "true";
else
cout << "false";
return 0;} //Driver Code Ends
Java
//Driver Code Starts import java.util.HashSet;
//Driver Code Ends
class Node { int data; Node next;
Node(int x) {
this.data = x;
this.next = null;
}}
class GfG { static boolean detectLoop(Node head) { HashSet st = new HashSet<>();
while (head != null) {
// if this node is already present
// in hashmap it means there is a cycle
if (st.contains(head))
return true;
// if we are seeing the node for
// the first time, insert it in hash
st.add(head);
head = head.next;
}
return false;
}//Driver Code Starts
public static void main(String[] args) {
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head))
System.out.println("true");
else
System.out.println("false");
}} //Driver Code Ends
Python
class Node: def init(self, x): self.data = x self.next = None
def detectLoop(head): st = set()
while head is not None:
# if this node is already present
# in hashmap it means there is a cycle
if head in st:
return True
# if we are seeing the node for
# the first time, insert it in hash
st.add(head)
head = head.next
return Falseif name == "main":
head = Node(1)
head.next = Node(3)
head.next.next = Node(4)
head.next.next.next = head.next
if detectLoop(head):
print("true")
else:
print("false")C#
//Driver Code Starts using System; using System.Collections.Generic;
//Driver Code Ends
class Node { public int data; public Node next;
public Node(int x) {
this.data = x;
this.next = null;
}}
class GfG { static bool detectLoop(Node head) { HashSet st = new HashSet();
while (head != null) {
// if this node is already present
// in hashmap it means there is a cycle
if (st.Contains(head))
return true;
// if we are seeing the node for
// the first time, insert it in hash
st.Add(head);
head = head.next;
}
return false;
}//Driver Code Starts
static void Main() {
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head))
Console.WriteLine("true");
else
Console.WriteLine("false");
}}
//Driver Code Ends
JavaScript
class Node { constructor(x) { this.data = x; this.next = null; } }
function detectLoop(head) { const st = new Set();
while (head !== null) {
// if this node is already present
// in hashmap it means there is a cycle
if (st.has(head))
return true;
// if we are seeing the node for
// the first time, insert it in hash
st.add(head);
head = head.next;
}
return false;}
//Driver Code Starts // Driver Code let head = new Node(1); head.next = new Node(3); head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head)) console.log("true"); else console.log("false"); //Driver Code Ends
`
[Expected Approach] Using Floyd's Cycle-Finding Algorithm - O(n) Time and O(1) Space
This idea is to use Floyd's Cycle-Finding Algorithm to find a loop in a linked list. It uses two pointers slow and fast, fast pointer move two steps ahead and slow will move one step ahead at a time.
**Algorithm:
- Traverse linked list using two pointers.
- 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:
**Why meeting is guaranteed if a cycle exists?
Let: **m = number of nodes before the cycle starts and **c = length of the cycle (number of nodes in the loop)
When both pointers enter the cycle: At that point, the difference in steps between fast and slow increases by 1 each turn (because fast moves 1 step more than slow each iteration). This difference is taken modulo c because positions wrap around inside the cycle.
**Mathematically:
- If d is the difference in positions (mod c), then each iteration: d ≡ d + 1 (mod c)
- Since 1 and c are coprime, adding 1 repeatedly cycles through all residues 0, 1, 2, …, c-1.
- Thus, eventually d ≡ 0 → meaning both pointers are at the same node (meeting point).
- For more details about the working & proof of this algorithm, Please refer to this article, How does Floyd’s Algorithm works. C++ `
//Driver Code Starts #include using namespace std; //Driver Code Ends
class Node { public: int data; Node* next; Node(int x) { this->data = x; this->next = nullptr; } };
bool detectLoop(Node* head) {
// Fast and slow pointers
// initially points to the head
Node *slow = head, *fast = head;
// Loop that runs while fast and slow pointer are not
// nullptr and not equal
while (slow && fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
// If fast and slow pointer points to the same node,
// then the cycle is detected
if (slow == fast) {
return true;
}
}
return false;}
//Driver Code Starts
int main() {
Node* head = new Node(1);
head->next = new Node(3);
head->next->next = new Node(4);
head->next->next->next = head->next;
if (detectLoop(head))
cout << "true";
else
cout << "false";
return 0;} //Driver Code Ends
C
//Driver Code Starts #include <stdbool.h> #include <stdio.h> #include <stdlib.h>
//Driver Code Ends
struct Node { int data; struct Node* next; };
struct Node* createNode(int new_data) { struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); new_node->data = new_data; new_node->next = NULL; return new_node; }
int detectLoop(struct Node* head) {
// Fast and slow pointers initially points to the head
struct Node *slow = head, *fast = head;
// Loop that runs while fast and slow pointer are not
// nullptr and not equal
while (slow && fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
// If fast and slow pointer points to the same node,
// then the cycle is detected
if (slow == fast) {
return true;
}
}
return false;}
//Driver Code Starts
int main() {
struct Node* head = createNode(1);
head->next = createNode(3);
head->next->next = createNode(4);
head->next->next->next = head->next;
if (detectLoop(head))
printf("true");
else
printf("false");
return 0;} //Driver Code Ends
Java
class Node { int data; Node next;
public Node(int x) {
this.data = x;
this.next = null;
}}
class GfG { static boolean detectLoop(Node head) {
// Fast and slow pointers initially points to the head
Node slow = head, fast = head;
// Loop that runs while fast and slow pointer are not
// null and not equal
while (slow != null && fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// If fast and slow pointer points to the same node,
// then the cycle is detected
if (slow == fast) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head))
System.out.println("true");
else
System.out.println("false");
}}
Python
class Node: def init(self, x): self.data = x self.next = None
def detectLoop(head):
# fast and slow pointers initially points to the head
slow = head
fast = head
# loop that runs while fast and slow pointer are not
# None and not equal
while slow and fast and fast.next:
slow = slow.next
fast = fast.next.next
# if fast and slow pointer points to the same node,
# then the cycle is detected
if slow == fast:
return True
return Falseif name == "main":
head = Node(1)
head.next = Node(3)
head.next.next = Node(4)
head.next.next.next = head.next
if detectLoop(head):
print("true")
else:
print("false")C#
using System;
class Node { public int data; public Node next;
public Node(int x) {
this.data = x;
this.next = null;
}}
class GfG { static bool detectLoop(Node head) {
// fast and slow pointers initially points to the head
Node slow = head, fast = head;
// loop that runs while fast and slow pointer are not
// null and not equal
while (slow != null && fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// if fast and slow pointer points to the same node,
// then the cycle is detected
if (slow == fast) {
return true;
}
}
return false;
}
static void Main() {
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head))
Console.WriteLine("true");
else
Console.WriteLine("false");
}}
JavaScript
class Node { constructor(x) { this.data = x; this.next = null; } }
function detectLoop(head) {
// fast and slow pointers
// initially points to the head
let slow = head, fast = head;
// Loop that runs while fast and slow pointer are not
// null and not equal
while (slow && fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
// If fast and slow pointer points to the same node,
// then the cycle is detected
if (slow === fast) {
return true;
}
}
return false;}
// Driver Code let head = new Node(1); head.next = new Node(3); head.next.next = new Node(4);
head.next.next.next = head.next;
if (detectLoop(head)) console.log("true"); else console.log("false");
`

