Skip to content

Instantly share code, notes, and snippets.

@leosabbir
Last active May 11, 2018 05:56
Show Gist options
  • Save leosabbir/de3896cbdf80e9bc41bf1c13a26ff8ea to your computer and use it in GitHub Desktop.
Save leosabbir/de3896cbdf80e9bc41bf1c13a26ff8ea to your computer and use it in GitHub Desktop.
Detecting Loop in a Linked List and Identify the Start of the Loop
/* File: DetectLoopInLinkedList.java
* Created: 2018-05-09
* Author: Sabbir Manandhar
*
* Copyright (c) 2018 Hogwart
*/
import java.util.HashSet;
import java.util.Set;
/**
* Detect Loop in a Linked List
*
* @author Sabbir Manandhar
* @version 1.0
*/
public class DetectLoopInLinkedList {
public static void main(String[] args) {
DetectLoopInLinkedList detectLoopInLinkedList = new DetectLoopInLinkedList();
int i = 1;
Node head = detectLoopInLinkedList.new Node(i++);
Node tail = head;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++); // 11
tail = tail.next;
Node loopBegin = tail;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
tail = tail.next;
tail.next = detectLoopInLinkedList.new Node(i++);
// No Loop
Node loopStart1 = detectLoopInLinkedList.detectLoop(head);
Node loopStart2 = detectLoopInLinkedList.detectLoopFloydMethod(head);
System.out.println(loopStart1 == null && loopStart2 == null ? "SUCCESS: Loop Not Found" : "Failure");
// Crate Loop at 11
tail = tail.next;
tail.next = loopBegin;
loopStart1 = detectLoopInLinkedList.detectLoop(head);
loopStart2 = detectLoopInLinkedList.detectLoopFloydMethod(head);
System.out.println(loopStart1 == loopStart2 ? "SUCCESS: Loop Start Found: " + loopStart1.value : "Failure");
} // main
//-----------------------------------------------------------------------------------
/**
* Detects a loop in a given LinkedList
* Based upon keeping track of already visited Nodes
* @param head head of the LinkedList
* @return start of loop if it exists, otherwise null
*/
public Node detectLoop(Node head) {
Set<Node> visitedNodes = new HashSet<Node>();
Node node = head;
while (node != null) {
if (visitedNodes.contains(node)) { // loop detected. node is the start of the loop
return node;
} else {
visitedNodes.add(node);
node = node.next;
}
}
return null; // no loop
} // detectLoop
//------------------------------------------------------------------------------------
/**
* Detect Loop in a LinkedList using Floyd's Method
* @param head Head of the LinkedList
* @return start of loop if it exists, otherwise null
*/
public Node detectLoopFloydMethod(Node head) {
Node faster = head;
Node slower = head;
// detect loop
while (faster != null && faster.next != null) {
faster = faster.next.next;
slower = slower.next;
if (faster == slower) { // loop detected
break;
}
}
if (faster != slower) return null; // loop not detected
// detect start of loop
faster = head;
while (faster != slower) {
faster = faster.next;
slower = slower.next;
}
return faster;
} // detectLoopFloydMethod
//------------------------------------------------------------------------------------
/**
* Class to represent Linked List Node
*/
public class Node {
Node next;
int value;
public Node(int value) {
this.value = value;
} // Node
} // Node
} // DetectLoopInLinkedList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment