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

3

**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

4-

**Explanation: The last node of the linked list points to NULL, indicating the end of the list.

Try It Yourselfredirect icon

Table of Content

[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 False

if 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:

**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:

//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 False

if 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");

`

Also Check: