## Wednesday, January 20, 2016

### How to find if the Linked List contains any Cycle/Loop?

DetectCycle in LinkedList using two pointers.

This solution is “Floyd’s Cycle-Finding Algorithm” as published in “Non-deterministic Algorithms” by Robert W. Floyd in 1967. It is also called “The Tortoise and the Hare Algorithm”.

O(n) time complexity
Simultaneously go through the list by ones (slow iterator) and by twos (fast iterator). If there is a loop the fast iterator will go around that loop twice as fast as the slow iterator. The fast iterator will lap the slow iterator within a single pass through the cycle. Detecting a loop is then just detecting that the slow iterator has been lapped by the fast iterator.

#### Steps

1. Use two pointers fast and slow
2. Move fast two nodes and slow one node in each iteration
3. If fast and slow meet then linked list contains cycle
4. if fast points to null or fast.next points to null then linked list is not cyclic
Java Source Code

``````public class CycleFreeLinkedList<T> {
private Node<T> first;
private Node<T> last;

public CycleFreeLinkedList() {
first = new Node<>();
}

public void appendToTail(T data) {
final Node l = last;
final Node<T> newNode = new Node(data);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
}

public void appendNodeToTail(Node<T> node) {
final Node l = last;
final Node<T> newNode = node;
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
}

public void detectCyclic() {
Node fast = first;
Node slow = first;

while (fast != null && fast.getNext() != null) {
fast = fast.getNext().getNext();
slow = slow.getNext();

//if fast and slow pointers are meeting then LinkedList is cyclic
if (fast == slow) {
throw new CyclicNodeException(fast.toString());
}
}
}

@Override
public String toString() {
detectCyclic();
StringBuilder output = new StringBuilder();
Node current = first.getNext();
while (current != null) {
output.append(current).append(" -> ");
current = current.getNext();
}
return output.toString();
}

public static class Node<T> {
Node next;
T data;

public Node() {
}

public Node(T data) {
this.data = data;
}

public Node getNext() {
return next;
}

public void setNext(Node next) {
this.next = next;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

@Override
public String toString() {
return "Node{" +
"data=" + data +
'}';
}
}

public static class CyclicNodeException extends RuntimeException {

public CyclicNodeException(String msg) {
super("There is a cyclic node in the list at - " + msg);
}
}
}``````

### Unit Test to detect Loops/Cycle

``````public class CycleFreeLinkedListTest {

@Rule
public ExpectedException thrown= ExpectedException.none();

@org.junit.Test
public void testIsNotCyclic() throws Exception {
CycleFreeLinkedList<String> linkedList = new CycleFreeLinkedList();
linkedList.appendToTail("101");
linkedList.appendToTail("201");
linkedList.appendToTail("301");
linkedList.appendToTail("401");

System.out.println("linkedList = " + linkedList);
}

@org.junit.Test
public void testIsCyclic() throws Exception {
CycleFreeLinkedList<String> linkedList = new CycleFreeLinkedList();
linkedList.appendToTail("101");

Node<String> cycle = new Node<>("201");

linkedList.appendNodeToTail(cycle);
linkedList.appendToTail("301");
linkedList.appendToTail("401");
linkedList.appendNodeToTail(cycle);

thrown.expect( CyclicNodeException.class );
thrown.expectMessage("There is a cyclic node in the list at - Node{data=401}");

System.out.println("linkedList = " + linkedList);
}
}``````

#### 1 comment:

1. Nice post Munish.
Could you please discuss some system design questions. How to approach them
Thanks

Your comment will be published after review from moderator