Detect and Remove Loop in Linked List (original) (raw)
Last Updated : 23 Jul, 2025
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 remove the loop from the linked list (if it exists).
**Example:
**Input:
**Output: 1 -> 3 -> 4
**Explanation: The Loop is removed from the above example.**Input:
**Output: 1 -> 8 -> 3 -> 4
**Explanation: There is no Loop in the above example.
Table of Content
- [Naive Approach] Detect and Remove Loop using Hashing - O(n) Time and O(n) Space
- [Efficient Approach] Using Floyd's Cycle Detection Algorithm - O(n) Time and O(1) Space
[Naive Approach] Detect and Remove Loop 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. Also, maintain a **prev pointer which points to the **previous node of the **current node. 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, then update the next pointer of **prev to **NULL to remove the loop from the linked list.
- else, if there is no node which is already **present in the **HashSet , then there is no loop in the linked list.
C++ `
//Driver Code Starts // C++ code to detect and remove loop in // linked list using hashing
#include <bits/stdc++.h> using namespace std;
struct Node { int data; Node *next;
Node(int x) {
data = x;
next = nullptr;
}};
void printList(Node *curr) { while (curr != nullptr) { cout << curr->data << " "; curr = curr->next; } cout << endl; } //Driver Code Ends
// Function to detect and remove loop in // a linked list void removeLoop(Node *head) {
// hash set to hash addresses of
// the linked list nodes
unordered_set<Node *> st;
// pointer to prev node
Node *prev = nullptr;
while (head != nullptr) {
// if node not present in the map,
// insert it in the map
if (st.find(head) == st.end()) {
st.insert(head);
prev = head;
head = head->next;
}
// if present, it is a cycle, make
// last node's next pointer NULL
else {
prev->next = nullptr;
break;
}
}}
//Driver Code Starts int main() {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node *head = new Node(1);
head->next = new Node(3);
head->next->next = new Node(4);
// Create a loop
head->next->next->next = head->next;
removeLoop(head);
printList(head);
return 0;} //Driver Code Ends
Java
//Driver Code Starts // Java code to detect and remove loop in linked // list using hashing
import java.util.HashSet;
class Node { int data; Node next;
Node(int x) {
data = x;
next = null;
}}
class GfG {
static void printList(Node curr) {
while (curr != null) {
System.out.print(curr.data + " ");
curr = curr.next;
}
System.out.println();
}//Driver Code Ends
// Function to detect and remove loop in a linked list
static void removeLoop(Node head) {
// hash set to hash addresses of
// the linked list nodes
HashSet<Node> st = new HashSet<>();
// pointer to prev node
Node prev = null;
while (head != null) {
// if node not present in the map,
// insert it in the map
if (!st.contains(head)) {
st.add(head);
prev = head;
head = head.next;
}
// if present, it is a cycle, make
// last node's next pointer NULL
else {
prev.next = null;
break;
}
}
}//Driver Code Starts public static void main(String[] args) {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
// Create a loop
head.next.next.next = head.next;
removeLoop(head);
printList(head);
}} //Driver Code Ends
Python
#Driver Code Starts
Python code to detect and remove loop in linked
list using hashing
class Node: def init(self, x): self.data = x self.next = None
def printList(curr):
# Function to print the linked list
while curr:
print(curr.data, end=' ')
curr = curr.next
print()#Driver Code Ends
def removeLoop(head):
# Function to detect and remove loop from linked list
nodeSet = set()
prev = None
while head:
# If node is already in the set, remove the loop
if head in nodeSet:
prev.next = None
return
# Add node to the set and move forward
nodeSet.add(head)
prev = head
head = head.next#Driver Code Starts if name == "main":
# Create a hard-coded linked list:
# 1 -> 3 -> 4
head = Node(1)
head.next = Node(3)
head.next.next = Node(4)
# Create a loop
head.next.next.next = head.next
removeLoop(head)
printList(head)#Driver Code Ends
C#
//Driver Code Starts // C# code to detect and remove loop in a // linked list using hashing
using System; using System.Collections.Generic;
class Node { public int data; public Node next;
public Node(int x) {
data = x;
next = null;
}}
class GfG { static void PrintList(Node curr) { while (curr != null) { Console.Write(curr.data + " "); curr = curr.next; } } //Driver Code Ends
// Function to detect and remove loop from linked list
static void removeLoop(Node head) {
HashSet<Node> st = new HashSet<Node>();
Node prev = null;
while (head != null) {
// If we have already seen this node in
// hash set, it means there is a cycle.
// Set the next of the previous pointer
// to null to remove the cycle.
if (st.Contains(head)) {
prev.next = null;
return;
}
// If we are seeing the node for the first time,
// insert it in hash set.
else {
st.Add(head);
prev = head;
head = head.next;
}
}
}//Driver Code Starts static void Main(string[] args) {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
// Create a loop
head.next.next.next = head.next;
removeLoop(head);
PrintList(head);
}}
//Driver Code Ends
JavaScript
//Driver Code Starts // JavaScript code to detect and remove loop in a // linked list using hashing
class Node { constructor(x) { this.data = x; this.next = null; } }
function printList(curr) { while (curr != null) { console.log(curr.data + " "); curr = curr.next; } } //Driver Code Ends
// Function to detect and remove loop from linked list function removeLoop(head) { let st = new Set(); let prev = null; while (head != null) {
// If node is already in the set, remove the loop
if (st.has(head)) {
prev.next = null;
return;
}
// Add node to the set and move forward
st.add(head);
prev = head;
head = head.next;
}}
//Driver Code Starts // Create a hard-coded linked list: // 1 -> 3 -> 4 head = new Node(1); head.next = new Node(3); head.next.next = new Node(4);
// Create a loop head.next.next.next = head.next;
removeLoop(head); printList(head);
//Driver Code Ends
`
Time Complexity: O(n), Where n is the number of nodes in the linked list.
Auxiliary Space: O(n), Where n is the number of nodes in the linked list(due to hashing).
[Efficient Approach] Using Floyd's Cycle 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:
- Use two pointers, **slow and **fast and initialize them with the **head of the linked list.
- Move the **fast pointer **forward by two nodes and move the **slow pointer forward by **one node.
- If the **slow and **fast pointer points to the **same node, **loop is found.
- Else if the fast pointer reaches **NULL, then **no loop is found.
- Else **repeat the above steps till we reach the **end of the linked list or a **loop is found.
2. Remove Loop in Linked List (if any):
The idea is similar to finding the starting node of Loop in a Linked List. For this, we will point 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->next is not equals to **slow->next. When **slow->next equals to fast->next we can easily point fast->next to NULL to remove the loop.
C++ `
//Driver Code Starts // C++ program Using Floyd's Cycle Detection Algorithm
#include <bits/stdc++.h> using namespace std;
struct Node { int data; Node *next;
Node(int x) {
data = x;
next = nullptr;
}};
void printList(Node *curr) { while (curr != nullptr) { cout << curr->data << " "; curr = curr->next; } cout << endl; } //Driver Code Ends
// Function to detect and remove loop in a linked list that // may contain loop void removeLoop(Node *head) {
// If list is empty or has only one node without loop
if (head == nullptr || head->next ==nullptr)
return;
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 exists
if (slow == fast) {
slow = head;
// this check is needed when slow and fast both meet
// at the head of the LL
if (slow == fast)
while (fast->next != slow)
fast = fast->next;
else {
while (slow->next != fast->next) {
slow = slow->next;
fast = fast->next;
}
}
// since fast->next is the looping point
fast->next = nullptr;
}}
//Driver Code Starts int main() {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node *head = new Node(1);
head->next = new Node(3);
head->next->next = new Node(4);
// Create a loop
head->next->next->next = head->next;
removeLoop(head);
printList(head);
return 0;} //Driver Code Ends
C
//Driver Code Starts // C program Using Floyd's Cycle Detection Algorithm
#include <stdio.h> #include <stdlib.h>
struct Node { int key; struct Node *next; };
void printList(struct Node *curr) { while (curr != NULL) { printf("%d ", curr->key); curr = curr->next; } printf(" "); } //Driver Code Ends
// Function to detect and remove loop in a linked list that // may contain loop void removeLoop(struct Node *head) {
// If list is empty or has only one node without loop
if (head == NULL || head->next == NULL)
return;
struct 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 exists
if (slow == fast) {
slow = head;
// this check is needed when slow and fast both meet
// at the head of the LL
if (slow == fast)
while (fast->next != slow)
fast = fast->next;
else {
while (slow->next != fast->next) {
slow = slow->next;
fast = fast->next;
}
}
// since fast->next is the looping point
// remove loop
fast->next = NULL;
}}
//Driver Code Starts struct Node *createNode(int key) { struct Node *curr = (struct Node *)malloc(sizeof(struct Node)); curr->key = key; curr->next = NULL; return curr; }
int main() {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
struct Node *head = createNode(1);
head->next = createNode(3);
head->next->next = createNode(4);
// Create a loop
head->next->next->next = head->next;
removeLoop(head);
printList(head);
return 0;} //Driver Code Ends
Java
//Driver Code Starts // Java program Using Floyd's Cycle Detection Algorithm class Node {
int data;
Node next;
Node(int x) {
data = x;
next = null;
}}
class GfG { //Driver Code Ends
// Function that detects loop in the list
static void removeLoop(Node head) {
// If list is empty or has only one node
// without loop
if (head == null || head.next == null)
return;
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 exists
if (slow == fast) {
slow = head;
if (slow != fast) {
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
// since fast->next is the looping point
// remove loop
fast.next = null;
}
// This case is added if fast and slow
// pointer meet at first position.
else {
while(fast.next != slow) {
fast = fast.next;
}
fast.next = null;
}
}
}//Driver Code Starts static void printList(Node curr) { while (curr != null) { System.out.print(curr.data + " "); curr = curr.next; } }
public static void main(String[] args) {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
// Create a loop
head.next.next.next = head.next;
removeLoop(head);
printList(head);
}}
//Driver Code Ends
Python
#Driver Code Starts
Python program Using Floyd's Cycle Detection Algorithm
class Node: def init(self, x): self.data = x self.next = None #Driver Code Ends
Function to remove the loop from the linked list
def removeLoop(head):
# If the list is empty or has only one node
# without a loop
if head is None or head.next is None:
return
slow = head
fast = head
# Move slow and fast pointers; slow moves 1 step,
# fast moves 2 steps
while slow and fast and fast.next:
slow = slow.next
fast = fast.next.next
# If slow and fast meet, a loop is detected
if slow == fast:
slow = head
# Move slow and fast pointers to find the node
# where the loop starts
while slow != fast:
slow = slow.next
fast = fast.next
# Traverse the loop to find the node where the
# loop ends and remove it
while fast.next != slow:
fast = fast.next
fast.next = None #Driver Code Starts def printList(curr): while curr: print(curr.data, end=' ') curr = curr.next print()
if name == "main":
# Create a linked list:
# 1 -> 3 -> 4
head = Node(1)
head.next = Node(3)
head.next.next = Node(4)
# Creating a loop
head.next.next.next = head.next
# Remove the loop from the linked list
removeLoop(head)
printList(head)#Driver Code Ends
C#
//Driver Code Starts // C# program Using Floyd's Cycle Detection Algorithm
class Node { public int data; public Node next;
public Node(int x) {
data = x;
next = null;
}}
class GfG { //Driver Code Ends
// Function that detects loop in the list
static void removeLoop(Node head) {
// If list is empty or has only one node
// without loop
if (head == null || head.next == null)
return;
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 exists
if (slow == fast) {
slow = head;
if (slow != fast) {
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
// since fast->next is the looping point
// remove loop
fast.next = null;
}
// This case is added if fast and slow pointer
// meet at first position.
else {
while (fast.next != slow) {
fast = fast.next;
}
fast.next = null;
}
}
}//Driver Code Starts static void printList(Node curr) { while (curr != null) { System.Console.Write(curr.data + " "); curr = curr.next; } }
static void Main(string[] args) {
// Create a hard-coded linked list:
// 1 -> 3 -> 4
Node head = new Node(1);
head.next = new Node(3);
head.next.next = new Node(4);
// Create a loop
head.next.next.next = head.next;
removeLoop(head);
printList(head);
}}
//Driver Code Ends
JavaScript
//Driver Code Starts // JavaScript program Using Floyd's Cycle Detection Algorithm
class Node { constructor(x) { this.data = x; this.next = null; } } //Driver Code Ends
// Function to detect and remove loop in the linked list function removeLoop(head) {
// If list is empty or has only one node without loop
if (head == null || head.next == null) return;
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 exists
if (slow == fast) {
slow = head;
// If the loop starts at the head of the list
if (slow != fast) {
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
// Remove the loop
fast.next = null;
} else {
// Special case when loop starts at the head
while (fast.next != slow) {
fast = fast.next;
}
fast.next = null;
}
}}
//Driver Code Starts function printList(curr) { let result = []; while (curr != null) { result.push(curr.data); curr = curr.next; } console.log(result.join(' ')); }
// Create a hard-coded linked list: // 1 -> 3 -> 4 let head = new Node(1); head.next = new Node(3); head.next.next = new Node(4);
// Create a loop head.next.next.next = head.next;
removeLoop(head); printList(head);
//Driver Code Ends
`
**Time Complexity: O(n), where n is the number of nodes in the Linked List
**Auxiliary Space: O(1)
For more details about the working & proof of this algorithm, Please refer to this article, How does Floyd’s Algorithm works.

