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.
[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>usingnamespacestd;structNode{intdata;Node*next;Node(intx){data=x;next=nullptr;}};voidprintList(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 listvoidremoveLoop(Node*head){// hash set to hash addresses of// the linked list nodesunordered_set<Node*>st;// pointer to prev nodeNode*prev=nullptr;while(head!=nullptr){// if node not present in the map,// insert it in the mapif(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 NULLelse{prev->next=nullptr;break;}}}//Driver Code Startsintmain(){// Create a hard-coded linked list: // 1 -> 3 -> 4Node*head=newNode(1);head->next=newNode(3);head->next->next=newNode(4);// Create a loophead->next->next->next=head->next;removeLoop(head);printList(head);return0;}//Driver Code Ends
Java
//Driver Code Starts// Java code to detect and remove loop in linked// list using hashingimportjava.util.HashSet;classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}classGfG{staticvoidprintList(Nodecurr){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 liststaticvoidremoveLoop(Nodehead){// hash set to hash addresses of// the linked list nodesHashSet<Node>st=newHashSet<>();// pointer to prev nodeNodeprev=null;while(head!=null){// if node not present in the map,// insert it in the mapif(!st.contains(head)){st.add(head);prev=head;head=head.next;}// if present, it is a cycle, make// last node's next pointer NULLelse{prev.next=null;break;}}}//Driver Code Startspublicstaticvoidmain(String[]args){// Create a hard-coded linked list:// 1 -> 3 -> 4Nodehead=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.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 hashingclassNode:def__init__(self,x):self.data=xself.next=NonedefprintList(curr):# Function to print the linked listwhilecurr:print(curr.data,end=' ')curr=curr.nextprint()#Driver Code EndsdefremoveLoop(head):# Function to detect and remove loop from linked listnodeSet=set()prev=Nonewhilehead:# If node is already in the set, remove the loopifheadinnodeSet:prev.next=Nonereturn# Add node to the set and move forwardnodeSet.add(head)prev=headhead=head.next#Driver Code Startsif__name__=="__main__":# Create a hard-coded linked list: # 1 -> 3 -> 4head=Node(1)head.next=Node(3)head.next.next=Node(4)# Create a loophead.next.next.next=head.nextremoveLoop(head)printList(head)#Driver Code Ends
C#
//Driver Code Starts// C# code to detect and remove loop in a // linked list using hashingusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGfG{staticvoidPrintList(Nodecurr){while(curr!=null){Console.Write(curr.data+" ");curr=curr.next;}}//Driver Code Ends// Function to detect and remove loop from linked liststaticvoidremoveLoop(Nodehead){HashSet<Node>st=newHashSet<Node>();Nodeprev=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 StartsstaticvoidMain(string[]args){// Create a hard-coded linked list: // 1 -> 3 -> 4Nodehead=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.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 hashingclassNode{constructor(x){this.data=x;this.next=null;}}functionprintList(curr){while(curr!=null){console.log(curr.data+" ");curr=curr.next;}}//Driver Code Ends// Function to detect and remove loop from linked listfunctionremoveLoop(head){letst=newSet();letprev=null;while(head!=null){// If node is already in the set, remove the loopif(st.has(head)){prev.next=null;return;}// Add node to the set and move forwardst.add(head);prev=head;head=head.next;}}//Driver Code Starts// Create a hard-coded linked list: // 1 -> 3 -> 4head=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.next.next.next=head.next;removeLoop(head);printList(head);//Driver Code Ends
Output
1 3 4
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
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>usingnamespacestd;structNode{intdata;Node*next;Node(intx){data=x;next=nullptr;}};voidprintList(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 loopvoidremoveLoop(Node*head){// If list is empty or has only one node without loopif(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 pointerswhile(fast&&fast->next){if(slow==fast)break;slow=slow->next;fast=fast->next->next;}// If loop existsif(slow==fast){slow=head;// this check is needed when slow and fast both meet// at the head of the LLif(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 Startsintmain(){// Create a hard-coded linked list:// 1 -> 3 -> 4Node*head=newNode(1);head->next=newNode(3);head->next->next=newNode(4);// Create a loophead->next->next->next=head->next;removeLoop(head);printList(head);return0;}//Driver Code Ends
C
//Driver Code Starts// C program Using Floyd's Cycle Detection Algorithm#include<stdio.h>#include<stdlib.h>structNode{intkey;structNode*next;};voidprintList(structNode*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 loopvoidremoveLoop(structNode*head){// If list is empty or has only one node without loopif(head==NULL||head->next==NULL)return;structNode*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 pointerswhile(fast&&fast->next){if(slow==fast)break;slow=slow->next;fast=fast->next->next;}// If loop existsif(slow==fast){slow=head;// this check is needed when slow and fast both meet// at the head of the LLif(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 loopfast->next=NULL;}}//Driver Code StartsstructNode*createNode(intkey){structNode*curr=(structNode*)malloc(sizeof(structNode));curr->key=key;curr->next=NULL;returncurr;}intmain(){// Create a hard-coded linked list:// 1 -> 3 -> 4structNode*head=createNode(1);head->next=createNode(3);head->next->next=createNode(4);// Create a loophead->next->next->next=head->next;removeLoop(head);printList(head);return0;}//Driver Code Ends
Java
//Driver Code Starts// Java program Using Floyd's Cycle Detection Algorithm classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}classGfG{//Driver Code Ends// Function that detects loop in the liststaticvoidremoveLoop(Nodehead){// If list is empty or has only one node// without loopif(head==null||head.next==null)return;Nodeslow=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 pointerswhile(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 StartsstaticvoidprintList(Nodecurr){while(curr!=null){System.out.print(curr.data+" ");curr=curr.next;}}publicstaticvoidmain(String[]args){// Create a hard-coded linked list:// 1 -> 3 -> 4Nodehead=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.next.next.next=head.next;removeLoop(head);printList(head);}}//Driver Code Ends
Python
#Driver Code Starts# Python program Using Floyd's Cycle Detection AlgorithmclassNode:def__init__(self,x):self.data=xself.next=None#Driver Code Ends# Function to remove the loop from the linked listdefremoveLoop(head):# If the list is empty or has only one node # without a loopifheadisNoneorhead.nextisNone:returnslow=headfast=head# Move slow and fast pointers; slow moves 1 step, # fast moves 2 stepswhileslowandfastandfast.next:slow=slow.nextfast=fast.next.next# If slow and fast meet, a loop is detectedifslow==fast:slow=head# Move slow and fast pointers to find the node # where the loop startswhileslow!=fast:slow=slow.nextfast=fast.next# Traverse the loop to find the node where the # loop ends and remove itwhilefast.next!=slow:fast=fast.nextfast.next=None#Driver Code StartsdefprintList(curr):whilecurr:print(curr.data,end=' ')curr=curr.nextprint()if__name__=="__main__":# Create a linked list:# 1 -> 3 -> 4head=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 listremoveLoop(head)printList(head)#Driver Code Ends
C#
//Driver Code Starts// C# program Using Floyd's Cycle Detection Algorithm classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classGfG{//Driver Code Ends// Function that detects loop in the liststaticvoidremoveLoop(Nodehead){// If list is empty or has only one node// without loopif(head==null||head.next==null)return;Nodeslow=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 pointerswhile(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 StartsstaticvoidprintList(Nodecurr){while(curr!=null){System.Console.Write(curr.data+" ");curr=curr.next;}}staticvoidMain(string[]args){// Create a hard-coded linked list:// 1 -> 3 -> 4Nodehead=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.next.next.next=head.next;removeLoop(head);printList(head);}}//Driver Code Ends
JavaScript
//Driver Code Starts// JavaScript program Using Floyd's Cycle Detection Algorithm classNode{constructor(x){this.data=x;this.next=null;}}//Driver Code Ends// Function to detect and remove loop in the linked listfunctionremoveLoop(head){// If list is empty or has only one node without loopif(head==null||head.next==null)return;letslow=head,fast=head;// Move slow and fast 1 and 2 steps // ahead respectivelyslow=slow.next;fast=fast.next.next;// Search for loop using slow and fast pointerswhile(fast!=null&&fast.next!=null){if(slow==fast)break;slow=slow.next;fast=fast.next.next;}// If loop existsif(slow==fast){slow=head;// If the loop starts at the head of the listif(slow!=fast){while(slow.next!=fast.next){slow=slow.next;fast=fast.next;}// Remove the loopfast.next=null;}else{// Special case when loop starts at the headwhile(fast.next!=slow){fast=fast.next;}fast.next=null;}}}//Driver Code StartsfunctionprintList(curr){letresult=[];while(curr!=null){result.push(curr.data);curr=curr.next;}console.log(result.join(' '));}// Create a hard-coded linked list:// 1 -> 3 -> 4lethead=newNode(1);head.next=newNode(3);head.next.next=newNode(4);// Create a loophead.next.next.next=head.next;removeLoop(head);printList(head);//Driver Code Ends
Output
1 3 4
Time Complexity: O(n), where n is the number of nodes in the Linked List Auxiliary Space: O(1)
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.