Cycle Start
by Isai Damier, Android Engineer @ Google

/***************************************************************************
 * Author: Isai Damier
 * Title: Singly Linked List
 * Project: geekviewpoint
 * Package: datastructure
 *
 * Description: A LinkedList is a data structure that allows access
 *   to a collection of data using pointers/references. While an
 *   array can also be defined as above, LinkedLists and arrays differ
 *   in how they are stored in memory and in the operations they
 *   allow. Unlike an array that must be stored in a block of memory,
 *   the nodes of a LinkedList can be stored anywhere because each
 *   node has a reference to the node that succeeds it. Because the
 *   nodes are stored so loosely, inserting nodes into a LinkedList
 *   is easy; whereas in an array, all the succeeding elements must
 *   be shifted. Of course, insertion also means changing the size of
 *   the array, which means creating the entire array anew.
 *
 *   Perhaps the greatest beauty of LinkedList is that it allows
 *   accessing an entire sequence of nodes using only one variable:
 *   a reference to the first node in the sequence.
 *
 *   Countless operations can be performed on LinkedLists. Following
 *   are a few, ranging from the common to the very interesting.
 **************************************************************************/ 
 public class SinglyLinkedList {

  Node head = null;
  Node tail = null;

  /*****************************************************************
   * Time Complexity of Solution:
   *   O(n).
   *
   * Description: If this LinkedList contains a loop/cycle, indicate
   *   the node where the cycle/loop begins. Understand that this
   *   LinkedList is not necessary circular: maybe it is; may be it
   *   is not. The LinkedList may be P-shaped. This algorithm will
   *   work either way.
   *
   * Technical Details: This algorithm was invented by R. W. Floyd.
   *   The basis for the algorithm is that if a path eventually
   *   loops, then two travelers walking at different speed will
   *   keep meeting each other.
   *
   *   Particularly. Let x and y be travelers such that y is walking
   *   twice as fast as x (i.e. y = 2x). Further, let s be the place
   *   where x and y first started walking at the same time. Then
   *   when x and y meet again, the distance from s to the start of
   *   the loop is the exact same distance from the present meeting
   *   place of x and y to the start of the loop.
   *
   *   BTY: reversing a P-shaped LinkedList still results in a
   *     P-shaped LinkedList with the same head and linear section;
   *     only the direction of the circular portion is reversed.
   *****************************************************************/
  public Node cycleStart() {
    if (null == head || null == head.next) {
      return null;
    }
    //slow and fast both started at head; after one step,
    //slow is at head.right and fast is at head.right.right
    Node slow = head.next;
    Node fast = slow.next;
    //each keep walking until they meet again.
    while (slow != fast) {
      slow = slow.next;
      try {
        fast = fast.next.next;
      } catch (NullPointerException n) {
        return null;//no cycle if null exception
      }
    }//while
    //from head to beginning of loop is same as from fast to
    //beginning of loop
    slow = head;
    while (slow != fast) {
      slow = slow.next;
      fast = fast.next;
    }
    return slow;//beginning of loop
  }
}
public class SinglyLinkedListTest {

   /**
   * Test of cycleStart method, of class SinglyLinkedList.
   */
  @Test
  public void testCycleStart() {
    System.out.println("cycleStart");
    int[] input = {9, 4, 5, 2, 1, 12, 6, 7, 4, 8, 3, 0, 16, 19, 11};
    SinglyLinkedList linkedList = new SinglyLinkedList();
    for (int i = 0; i < input.length; i++) {
      linkedList.addToTail(input[i]);
    }
    Node cy = linkedList.find(18);
    linkedList.tail.right = cy;
    assertEquals(cy, linkedList.cycleStart());
  }
}