Write a function detectAndRemoveLoop() that checks whether a given Linked List contains a loop and if the loop is present then remove the loop and return true. If the list doesn’t contain a loop then it returns false. The below diagram shows a linked list with a loop. detectAndRemoveLoop() must change the below list to 1->2->3->4->5->NULL.

We also recommend reading the following post as a prerequisite to the solution discussed here.
Write a C function to detect a loop in a linked list
Before trying to remove the loop, we must detect it. Techniques discussed in the above post can be used to detect loops. To remove the loop, all we need to do is to get a pointer to the last node of the loop. For example, a node with value 5 in the above diagram. Once we have a pointer to the last node, we can make the next of this node NULL and the loop is gone.
We can easily use Hashing or Visited node techniques (discussed in the above-mentioned post) to get the pointer to the last node. The idea is simple: the very first node whose next is already visited (or hashed) is the last node.
We can also use the Floyd Cycle Detection algorithm to detect and remove the loop. In Floyd’s algo, the slow and fast pointers meet at a loop node. We can use this loop node to remove the cycle. There are following two different ways of removing the loop when Floyd’s algorithm is used for loop detection.
Method 1 (Check one by one) We know that Floyd’s Cycle detection algorithm terminates when fast and slow pointers meet at a common point. We also know that this common point is one of the loop nodes (2 or 3 or 4 or 5 in the above diagram). Store the address of this in a pointer variable say ptr2. After that start from the head of the Linked List and check for nodes one by one if they are reachable from ptr2. Whenever we find a node that is reachable, we know that this node is the starting node of the loop in the Linked List and we can get the pointer to the previous of this node.
Output:
Linked List after removing loop
50 20 15 4 10
Method 2 (Better Solution)
- This method is also dependent on Floyd’s Cycle detection algorithm.
- Detect Loop using Floyd’s Cycle detection algorithm and get the pointer to a loop node.
- Count the number of nodes in the loop. Let the count be k.
- Fix one pointer to the head and another to a kth node from the head.
- Move both pointers at the same pace, they will meet at the loop starting node.
- Get a pointer to the last node of the loop and make the next of it NULL.
Thanks to WgpShashank for suggesting this method.
Below image is a dry run of the ‘remove loop’ function in the code :

C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
void removeLoop( struct Node*, struct Node*);
int detectAndRemoveLoop( struct Node* list)
{
struct Node *slow_p = list, *fast_p = list;
while (slow_p && fast_p && fast_p->next) {
slow_p = slow_p->next;
fast_p = fast_p->next->next;
if (slow_p == fast_p) {
removeLoop(slow_p, list);
return 1;
}
}
return 0;
}
void removeLoop( struct Node* loop_node, struct Node* head)
{
struct Node* ptr1 = loop_node;
struct Node* ptr2 = loop_node;
unsigned int k = 1, i;
while (ptr1->next != ptr2) {
ptr1 = ptr1->next;
k++;
}
ptr1 = head;
ptr2 = head;
for (i = 0; i < k; i++)
ptr2 = ptr2->next;
while (ptr2 != ptr1) {
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
while (ptr2->next != ptr1)
ptr2 = ptr2->next;
ptr2->next = NULL;
}
void printList( struct Node* node)
{
while (node != NULL) {
cout << node->data << " " ;
node = node->next;
}
}
struct Node* newNode( int key)
{
struct Node* temp = new Node();
temp->data = key;
temp->next = NULL;
return temp;
}
int main()
{
struct Node* head = newNode(50);
head->next = newNode(20);
head->next->next = newNode(15);
head->next->next->next = newNode(4);
head->next->next->next->next = newNode(10);
head->next->next->next->next->next = head->next->next;
detectAndRemoveLoop(head);
cout << "Linked List after removing loop \n" ;
printList(head);
return 0;
}
|
Java
class LinkedList {
static Node head;
static class Node {
int data;
Node next;
Node( int d)
{
data = d;
next = null ;
}
}
int detectAndRemoveLoop(Node node)
{
Node slow = node, fast = node;
while (slow != null && fast != null
&& fast.next != null ) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
removeLoop(slow, node);
return 1 ;
}
}
return 0 ;
}
void removeLoop(Node loop, Node head)
{
Node ptr1 = loop;
Node ptr2 = loop;
int k = 1 , i;
Node prevNode = ptr1;
while (ptr1.next != ptr2) {
prevNode = ptr1;
ptr1 = ptr1.next;
k++;
}
prevNode.next = null ;
}
void printList(Node node)
{
while (node != null ) {
System.out.print(node.data + " " );
node = node.next;
}
}
public static void main(String[] args)
{
LinkedList list = new LinkedList();
list.head = new Node( 50 );
list.head.next = new Node( 20 );
list.head.next.next = new Node( 15 );
list.head.next.next.next = new Node( 4 );
list.head.next.next.next.next = new Node( 10 );
head.next.next.next.next.next = head.next.next;
list.detectAndRemoveLoop(head);
System.out.println(
"Linked List after removing loop : " );
list.printList(head);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
class LinkedList:
def __init__( self ):
self .head = None
def detectAndRemoveLoop( self ):
slow_p = fast_p = self .head
while (slow_p and fast_p and fast_p. next ):
slow_p = slow_p. next
fast_p = fast_p. next . next
if slow_p = = fast_p:
self .removeLoop(slow_p)
return 1
return 0
def removeLoop( self , loop_node):
ptr1 = loop_node
ptr2 = loop_node
k = 1
while (ptr1. next ! = ptr2):
ptr1 = ptr1. next
k + = 1
ptr1 = self .head
ptr2 = self .head
for i in range (k):
ptr2 = ptr2. next
while (ptr2 ! = ptr1):
ptr1 = ptr1. next
ptr2 = ptr2. next
while (ptr2. next ! = ptr1):
ptr2 = ptr2. next
ptr2. next = None
def push( self , new_data):
new_node = Node(new_data)
new_node. next = self .head
self .head = new_node
def printList( self ):
temp = self .head
while (temp):
print (temp.data, end = ' ' )
temp = temp. next
llist = LinkedList()
llist.push( 10 )
llist.push( 4 )
llist.push( 15 )
llist.push( 20 )
llist.push( 50 )
llist.head. next . next . next . next . next = llist.head. next . next
llist.detectAndRemoveLoop()
print ( "Linked List after removing loop" )
llist.printList()
|
C#
using System;
public class LinkedList {
Node head;
public class Node {
public int data;
public Node next;
public Node( int d)
{
data = d;
next = null ;
}
}
int detectAndRemoveLoop(Node node)
{
Node slow = node, fast = node;
while (slow != null && fast != null && fast.next != null ) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
removeLoop(slow, node);
return 1;
}
}
return 0;
}
void removeLoop(Node loop, Node head)
{
Node ptr1 = loop;
Node ptr2 = loop;
int k = 1, i;
while (ptr1.next != ptr2) {
ptr1 = ptr1.next;
k++;
}
ptr1 = head;
ptr2 = head;
for (i = 0; i < k; i++) {
ptr2 = ptr2.next;
}
while (ptr2 != ptr1) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
while (ptr2.next != ptr1) {
ptr2 = ptr2.next;
}
ptr2.next = null ;
}
void printList(Node node)
{
while (node != null ) {
Console.Write(node.data + " " );
node = node.next;
}
}
public static void Main(String[] args)
{
LinkedList list = new LinkedList();
list.head = new Node(50);
list.head.next = new Node(20);
list.head.next.next = new Node(15);
list.head.next.next.next = new Node(4);
list.head.next.next.next.next = new Node(10);
list.head.next.next.next.next.next = list.head.next.next;
list.detectAndRemoveLoop(list.head);
Console.WriteLine( "Linked List after removing loop : " );
list.printList(list.head);
}
}
|
Javascript
<script>
var head;
class Node
{
constructor(val)
{
this .data = val;
this .next = null ;
}
}
function detectAndRemoveLoop(node)
{
var slow = node, fast = node;
while (slow != null &&
fast != null &&
fast.next != null )
{
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
{
removeLoop(slow, node);
return 1;
}
}
return 0;
}
function removeLoop(loop, head)
{
var ptr1 = loop;
var ptr2 = loop;
var k = 1, i;
while (ptr1.next != ptr2)
{
ptr1 = ptr1.next;
k++;
}
ptr1 = head;
ptr2 = head;
for (i = 0; i < k; i++)
{
ptr2 = ptr2.next;
}
while (ptr2 != ptr1)
{
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
while (ptr2.next != ptr1)
{
ptr2 = ptr2.next;
}
ptr2.next = null ;
}
function printList(node)
{
while (node != null )
{
document.write(node.data + " " );
node = node.next;
}
}
head = new Node(50);
head.next = new Node(20);
head.next.next = new Node(15);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(10);
head.next.next.next.next.next = head.next.next;
detectAndRemoveLoop(head);
document.write( "Linked List after removing loop : " );
printList(head);
</script>
|
OutputLinked List after removing loop
50 20 15 4 10
Time Complexity: O(N), Where N is the number of nodes in the tree
Auxiliary Space: O(1)
Method 3 (Optimized Method 2: Without Counting Nodes in Loop)
We do not need to count the number of nodes in Loop. After detecting the loop, if we start the slow pointer from the head and move both slow and fast pointers at the same speed until fast don’t meet, they would meet at the beginning of the loop.
How does this work?
Let slow and fast meet at some point after Floyd’s Cycle finding algorithm. The below diagram shows the situation when the cycle is found.

Situation when cycle is found
We can conclude below from the above diagram
Distance traveled by fast pointer = 2 * (Distance traveled
by slow pointer)
(m + n*x + k) = 2*(m + n*y + k)
Note that before meeting the point shown above, fast
was moving at twice speed.
x --> Number of complete cyclic rounds made by
fast pointer before they meet first time
y --> Number of complete cyclic rounds made by
slow pointer before they meet first time
From the above equation, we can conclude below
m + k = (x-2y)*n
Which means m+k is a multiple of n.
Thus we can write, m + k = i*n or m = i*n - k.
Hence, distance moved by slow pointer: m, is equal to distance moved by fast pointer:
i*n - k or (i-1)*n + n - k (cover the loop completely i-1 times and start from n-k).
So if we start moving both pointers again at same speed such that one pointer (say slow) begins from head node of linked list and other pointer (say fast) begins from meeting point. When the slow pointer reaches the beginning of the loop (has made m steps), the fast pointer would have made also moved m steps as they are now moving at the same pace. Since m+k is a multiple of n and fast starts from k, they would meet at the beginning. Can they meet before also? No because slow pointer enters the cycle first time after m steps.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node* next;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->next = NULL;
return temp;
}
void printList(Node* head)
{
while (head != NULL) {
cout << head->key << " " ;
head = head->next;
}
cout << endl;
}
void detectAndRemoveLoop(Node* head)
{
if (head == NULL || head->next == NULL)
return ;
Node *slow = head, *fast = head;
slow = slow->next;
fast = fast->next->next;
while (fast && fast->next) {
if (slow == fast)
break ;
slow = slow->next;
fast = fast->next->next;
}
if (slow == fast) {
slow = head;
if (slow == fast)
while (fast->next != slow)
fast = fast->next;
else {
while (slow->next != fast->next) {
slow = slow->next;
fast = fast->next;
}
}
fast->next = NULL;
}
}
int main()
{
Node* head = newNode(50);
head->next = head;
head->next = newNode(20);
head->next->next = newNode(15);
head->next->next->next = newNode(4);
head->next->next->next->next = newNode(10);
head->next->next->next->next->next = head;
detectAndRemoveLoop(head);
printf ( "Linked List after removing loop \n" );
printList(head);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int key;
struct Node* next;
} Node;
Node* newNode( int key)
{
Node* temp = (Node*) malloc ( sizeof (Node));
temp->key = key;
temp->next = NULL;
return temp;
}
void printList(Node* head)
{
while (head != NULL) {
printf ( "%d " , head->key);
head = head->next;
}
printf ( "\n" );
}
void detectAndRemoveLoop(Node* head)
{
if (head == NULL || head->next == NULL)
return ;
Node *slow = head, *fast = head;
slow = slow->next;
fast = fast->next->next;
while (fast && fast->next) {
if (slow == fast)
break ;
slow = slow->next;
fast = fast->next->next;
}
if (slow == fast) {
slow = head;
if (slow == fast)
while (fast->next != slow)
fast = fast->next;
else {
while (slow->next != fast->next) {
slow = slow->next;
fast = fast->next;
}
}
fast->next = NULL;
}
}
int main()
{
Node* head = newNode(50);
head->next = head;
head->next = newNode(20);
head->next->next = newNode(15);
head->next->next->next = newNode(4);
head->next->next->next->next = newNode(10);
head->next->next->next->next->next = head;
detectAndRemoveLoop(head);
printf ( "Linked List after removing loop \n" );
printList(head);
return 0;
}
|
Java
class LinkedList {
static Node head;
static class Node {
int data;
Node next;
Node( int d)
{
data = d;
next = null ;
}
}
void detectAndRemoveLoop(Node node)
{
if (node == null || node.next == null )
return ;
Node slow = node, fast = node;
slow = slow.next;
fast = fast.next.next;
while (fast != null && fast.next != null ) {
if (slow == fast)
break ;
slow = slow.next;
fast = fast.next.next;
}
if (slow == fast) {
slow = node;
if (slow != fast) {
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
fast.next = null ;
}
else {
while (fast.next != slow) {
fast = fast.next;
}
fast.next = null ;
}
}
}
void printList(Node node)
{
while (node != null ) {
System.out.print(node.data + " " );
node = node.next;
}
}
public static void main(String[] args)
{
LinkedList list = new LinkedList();
list.head = new Node( 50 );
list.head.next = new Node( 20 );
list.head.next.next = new Node( 15 );
list.head.next.next.next = new Node( 4 );
list.head.next.next.next.next = new Node( 10 );
head.next.next.next.next.next = head.next.next;
list.detectAndRemoveLoop(head);
System.out.println( "Linked List after removing loop : " );
list.printList(head);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
class LinkedList:
def __init__( self ):
self .head = None
def push( self , new_data):
new_node = Node(new_data)
new_node. next = self .head
self .head = new_node
def detectAndRemoveLoop( self ):
if self .head is None :
return
if self .head. next is None :
return
slow_p = self .head
fast_p = self .head
while (slow_p and fast_p and fast_p. next ):
slow_p = slow_p. next
fast_p = fast_p. next . next
if slow_p = = fast_p:
slow_p = self .head
while (slow_p. next ! = fast_p. next ):
slow_p = slow_p. next
fast_p = fast_p. next
fast_p. next = None
def printList( self ):
temp = self .head
while (temp):
print (temp.data, end = ' ' )
temp = temp. next
llist = LinkedList()
llist.head = Node( 50 )
llist.head. next = Node( 20 )
llist.head. next . next = Node( 15 )
llist.head. next . next . next = Node( 4 )
llist.head. next . next . next . next = Node( 10 )
llist.head. next . next . next . next . next = llist.head. next . next
llist.detectAndRemoveLoop()
print ( "Linked List after removing loop" )
llist.printList()
|
C#
using System;
public class LinkedList {
public Node head;
public class Node {
public int data;
public Node next;
public Node( int d)
{
data = d;
next = null ;
}
}
void detectAndRemoveLoop(Node node)
{
if (node == null || node.next == null )
return ;
Node slow = node, fast = node;
slow = slow.next;
fast = fast.next.next;
while (fast != null && fast.next != null ) {
if (slow == fast)
break ;
slow = slow.next;
fast = fast.next.next;
}
if (slow == fast) {
slow = node;
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
fast.next = null ;
}
}
void printList(Node node)
{
while (node != null ) {
Console.Write(node.data + " " );
node = node.next;
}
}
public static void Main(String[] args)
{
LinkedList list = new LinkedList();
list.head = new Node(50);
list.head.next = new Node(20);
list.head.next.next = new Node(15);
list.head.next.next.next = new Node(4);
list.head.next.next.next.next = new Node(10);
list.head.next.next.next.next.next = list.head.next.next;
list.detectAndRemoveLoop(list.head);
Console.WriteLine( "Linked List after removing loop : " );
list.printList(list.head);
}
}
|
Javascript
<script>
var head;
class Node
{
constructor(val)
{
this .data = val;
this .next = null ;
}
}
function detectAndRemoveLoop(node) {
if (node == null || node.next == null )
return ;
var slow = node, fast = node;
slow = slow.next;
fast = fast.next.next;
while (fast != null && fast.next != null ) {
if (slow == fast)
break ;
slow = slow.next;
fast = fast.next.next;
}
if (slow == fast) {
slow = node;
if (slow != fast) {
while (slow.next != fast.next) {
slow = slow.next;
fast = fast.next;
}
fast.next = null ;
}
else {
while (fast.next != slow) {
fast = fast.next;
}
fast.next = null ;
}
}
}
function printList(node) {
while (node != null ) {
document.write(node.data + " " );
node = node.next;
}
}
head = new Node(50);
head.next = new Node(20);
head.next.next = new Node(15);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(10);
head.next.next.next.next.next = head.next.next;
detectAndRemoveLoop(head);
document.write( "Linked List after removing loop : " );
printList(head);
</script>
|
OutputLinked List after removing loop
50 20 15 4 10
Time Complexity: O(N), Where N is the number of nodes in the tree
Auxiliary Space: O(1)
Method 4 Hashing: Hash the address of the linked list nodes
We can hash the addresses of the linked list nodes in an unordered map and just check if the element already exists in the map. If it exists, we have reached a node that already exists by a cycle, hence we need to make the last node’s next pointer NULL.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node* next;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->next = NULL;
return temp;
}
void printList(Node* head)
{
while (head != NULL) {
cout << head->key << " " ;
head = head->next;
}
cout << endl;
}
void hashAndRemove(Node* head)
{
unordered_map<Node*, int > node_map;
Node* last = NULL;
while (head != NULL) {
if (node_map.find(head) == node_map.end()) {
node_map[head]++;
last = head;
head = head->next;
}
else {
last->next = NULL;
break ;
}
}
}
int main()
{
Node* head = newNode(50);
head->next = head;
head->next = newNode(20);
head->next->next = newNode(15);
head->next->next->next = newNode(4);
head->next->next->next->next = newNode(10);
head->next->next->next->next->next = head->next->next;
hashAndRemove(head);
printf ( "Linked List after removing loop \n" );
printList(head);
return 0;
}
|
Java
import java.util.*;
public class LinkedList {
static Node head;
static class Node {
int data;
Node next;
Node( int d)
{
data = d;
next = null ;
}
}
static public void push( int new_data)
{
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
void printList(Node node)
{
while (node != null ) {
System.out.print(node.data + " " );
node = node.next;
}
}
static boolean removeLoop(Node h)
{
HashSet<Node> s = new HashSet<Node>();
Node prev = null ;
while (h != null ) {
if (s.contains(h)) {
prev.next = null ;
return true ;
}
else {
s.add(h);
prev = h;
h = h.next;
}
}
return false ;
}
public static void main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push( 20 );
llist.push( 4 );
llist.push( 15 );
llist.push( 10 );
llist.head.next.next.next.next = llist.head;
if (removeLoop(head)) {
System.out.println( "Linked List after removing loop" );
llist.printList(head);
}
else
System.out.println( "No Loop found" );
}
}
|
C#
using System;
using System.Collections.Generic;
public class LinkedList {
public Node head;
public class Node {
public int data;
public Node next;
public Node( int d)
{
data = d;
next = null ;
}
}
void printList(Node node)
{
while (node != null ) {
Console.Write(node.data + " " );
node = node.next;
}
}
bool removeLoop(Node h)
{
HashSet<Node> s = new HashSet<Node>();
Node prev = null ;
while (h != null ) {
if (s.Contains(h)) {
prev.next = null ;
return true ;
}
else {
s.Add(h);
prev = h;
h = h.next;
}
}
return false ;
}
public static void Main()
{
LinkedList list = new LinkedList();
list.head = new Node(50);
list.head.next = new Node(20);
list.head.next.next = new Node(15);
list.head.next.next.next = new Node(4);
list.head.next.next.next.next = new Node(10);
list.head.next.next.next.next.next = list.head.next.next;
if (list.removeLoop(list.head)) {
Console.WriteLine( "Linked List after removing loop" );
list.printList(list.head);
}
else
Console.WriteLine( "No Loop found" );
}
}
|
Javascript
<script>
class Node {
constructor(val) {
this .data = val;
this .next = null ;
}
}
var head;
function push(new_data) {
var new_node = new Node(new_data);
new_node.next = head;
head = new_node;
return head;
}
function printList(node) {
while (node != null ) {
document.write(node.data + " " );
node = node.next;
}
}
function removeLoop(h)
{
var s = new Set();
var prev = null ;
while (h != null )
{
if (s.has(h)) {
prev.next = null ;
return true ;
}
else {
s.add(h);
prev = h;
h = h.next;
}
}
return false ;
}
head = push(50);
head.next = push(20);
head.next.next=push(4);
head.next.next.next=push(15);
head.next.next.next.next=push(10);
head.next.next.next.next.next = head.next.next;
if (removeLoop(head)) {
document.write( "Linked List after removing loop<br/>" );
printList(head);
} else
document.write( "No Loop found" );
</script>
|
Python
class LinkedList:
head = None
class Node:
data = 0
next = None
def __init__( self , d):
self .data = d
self . next = None
@staticmethod
def push(new_data):
new_node = LinkedList.Node(new_data)
new_node. next = LinkedList.head
LinkedList.head = new_node
def printList( self , node):
while (node ! = None ):
print (node.data)
node = node. next
@staticmethod
def removeLoop(h):
s = set ()
prev = None
while (h ! = None ):
if (h in s):
prev. next = None
return True
else :
s.add(h)
prev = h
h = h. next
return False
@staticmethod
def main(args):
llist = LinkedList()
llist.push( 20 )
llist.push( 4 )
llist.push( 15 )
llist.push( 10 )
llist.head. next . next . next . next = llist.head
if (LinkedList.removeLoop(LinkedList.head)):
print ( "Linked List after removing loop" )
llist.printList(LinkedList.head)
else :
print ( "No Loop found" )
if __name__ = = "__main__" :
LinkedList.main([])
|
OutputLinked List after removing loop
50 20 15 4 10
Time Complexity: O(N), Where N is the number of nodes in the tree.
Auxiliary Space: O(N), Where N is the number of nodes in the tree (due to hashing).
Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem