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.

Try It Yourselfredirect icon

Table of Content

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

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:

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.