Detect loop or cycle in a linked list
Last Updated :
09 Sep, 2024
Given a singly linked list, check if the linked list has a loop (cycle) or not. A loop means that the last node of the linked list is connected back to a node in the same list.
Examples:
Input: head: 1 -> 3 -> 4 -> NULL
Output: true
Input: head: 1 -> 8 -> 3 -> 4 -> NULL
Output: false
[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 then return true.
Follow the steps below to solve the problem:
- Initialize an empty HashSet to store the addresses (or references) of the visited nodes.
- Start traversing the linked list from head and for every node check if its address (or reference) is already in the HashSet
- If the node is NULL, represents the end of Linked List , return false as there is no loop.
- If the node’s address is not in the HashSet, add it to the HashSet.
- If the node’s address is already in the HashSet, which indicates there’s a cycle (loop) in the list. In this case, return true.
Below is the implementation of the above approach:
C++
// C++ program to detect loop in a linked list
// using hashset
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
this->data = x;
this->next = nullptr;
}
};
// Function that returns true if there is a loop in linked
// list else returns false.
bool detectLoop(Node* head) {
unordered_set<Node*>st;
// loop that runs till the head is nullptr
while (head != nullptr) {
// If this node is already present
// in hashmap it means there is a cycle
// (Because you will be encountering the
// node for the second time).
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;
}
int main() {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
Node* head = new Node(10);
head->next = new Node(20);
head->next->next = new Node(30);
head->next->next->next = new Node(40);
head->next->next->next->next = new Node(50);
head->next->next->next->next->next = new Node(60);
head->next->next->next->next = head;
if (detectLoop(head))
cout << "true";
else
cout << "false";
return 0;
}
Java
// Java program to detect loop in a linked list
// using hashset
import java.util.HashSet;
import java.util.Set;
class Node {
int data;
Node next;
Node(int x) {
this.data = x;
this.next = null;
}
}
class GfG {
// Function that returns true if there is a loop in
// linked list else returns false.
static boolean detectLoop(Node head) {
Set<Node> st = new HashSet<>();
// loop that runs till the head is null
while (head != null) {
// If this node is already present
// in hashmap it means there is a cycle
// (Because you will be encountering the
// node for the second time).
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;
}
public static void main(String[] args) {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
Node head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
System.out.println("true");
else
System.out.println("false");
}
}
Python
# Python program to detect loop
# in the linked list using hashset
class Node:
def __init__(self, x):
self.data = x
self.next = None
# Function that returns true if there is a loop in linked
# list else returns false.
def detect_loop(head):
st = set()
# loop that runs till the head is None
while head is not None:
# If this node is already present
# in hashmap it means there is a cycle
# (Because you will be encountering the
# node for the second time).
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
# Create a hard-coded linked list:
# 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
head.next.next.next.next = Node(50)
head.next.next.next.next.next = Node(60)
head.next.next.next.next = head
if detect_loop(head):
print("true")
else:
print("false")
C#
// C# program to detect loop in a linked list
// using hashset
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int x) {
this.data = x;
this.next = null;
}
}
class GfG {
// Function that returns true if there is a loop in
// linked list else returns false.
public static bool detectLoop(Node head) {
HashSet<Node> st = new HashSet<Node>();
// loop that runs till the head is null
while (head != null) {
// If this node is already present
// in hashmap it means there is a cycle
// (Because you will be encountering the
// node for the second time).
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;
}
static void Main() {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
Node head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
JavaScript
// JavaScript program to detect loop in a linked list
// using hashset
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function that returns true if there is a loop in
// linked list else returns false.
function detectLoop(head) {
let st = new Set();
// loop that runs till the head is null
while (head !== null) {
// If this node is already present
// in hashmap it means there is a cycle
// (Because you will be encountering the
// node for the second time).
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;
}
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
let head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
console.log("true");
else
console.log("false");
Time complexity: O(n), where n is the number of nodes in the Linked List.
Auxiliary Space: O(n), n is the space required to store the value in the hash set.
[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.
Follow the steps below to solve the problem:
- 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:
For more details about the working & proof of this algorithm, Please refer to this article, How does Floyd’s Algorithm works.
C++
// C++ program to detect loop in a linked list
// using Floyd's Cycle-Finding Algorithm
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
this->data = x;
this->next = nullptr;
}
};
// Function that returns true if there is a loop in linked
// list else returns false.
int 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 1;
}
}
return 0;
}
int main() {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
Node* head = new Node(10);
head->next = new Node(20);
head->next->next = new Node(30);
head->next->next->next = new Node(40);
head->next->next->next->next = new Node(50);
head->next->next->next->next->next = new Node(60);
head->next->next->next->next = head;
if (detectLoop(head))
cout << "true";
else
cout << "false";
return 0;
}
C
// C program to detect loop in a linked list
// using Floyd's Cycle-Finding Algorithm
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// A linked list node
struct Node {
int data;
struct Node* next;
};
// Function that returns true if there is a loop in linked
// list else returns false.
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 1;
}
}
return 0;
}
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 main() {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
struct Node* head = createNode(10);
head->next = createNode(20);
head->next->next = createNode(30);
head->next->next->next = createNode(40);
head->next->next->next->next = createNode(50);
head->next->next->next->next->next = createNode(60);
head->next->next->next->next = head;
if (detectLoop(head))
printf("true");
else
printf("false");
return 0;
}
Java
// Java program to detect loop in a linked list
// using Floyd's Cycle-Finding Algorithm
import java.util.*;
class Node {
int data;
Node next;
Node(int x) {
this.data = x;
this.next = null;
}
}
class GfG {
// Function that returns true if there is a loop in
// linked list else returns false.
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) {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
Node head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
System.out.println("true");
else
System.out.println("false");
}
}
Python
# C++ program to detect loop in a linked list
# using Floyd's Cycle-Finding Algorithm
class Node:
def __init__(self, new_data):
self.data = new_data
self.next = None
# Function that returns true if there is a loop in linked
# list else returns false.
def detect_loop(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
# Create a hard-coded linked list:
# 10 -> 20 -> 30 -> 40 -> 50 -> 60
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
head.next.next.next.next = Node(50)
head.next.next.next.next.next = Node(60)
head.next.next.next.next = head
if detect_loop(head):
print("true")
else:
print("false")
C#
// C# program to detect loop in a linked list
// using Floyd's Cycle-Finding Algorithm
using System;
class Node {
public int data;
public Node next;
public Node(int x) {
this.data = x;
this.next = null;
}
}
class GfG {
// Function that returns true if there is a loop in linked
// list else returns false.
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() {
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
Node head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
JavaScript
// Javascript program to detect loop in a linked list
// using Floyd's Cycle-Finding Algorithm
class Node {
constructor(x) {
this.data = x;
this.next = null;
}
}
// Function that returns true if there is a loop in
// linked list else returns false.
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 !== 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;
}
// Create a hard-coded linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60
let head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
head.next.next.next.next.next = new Node(60);
head.next.next.next.next = head;
if (detectLoop(head))
console.log("true");
else
console.log("false");
Time complexity: O(n), where n is the number of nodes in the Linked List.
Auxiliary Space: O(1).
Related Article: