0

This code is for finding the loop in a single linked list and i have learned about it from http://blog.ostermiller.org/find-loop-singly-linked-list but could not get my head around why the code has been written the way it has been written.

This solution was devised by Stephen Ostermiller and proven O(n) by Daniel Martin.

function boolean hasLoop(Node startNode){
  Node currentNode = startNode;
  Node checkNode = null;
  int since = 0;
  int sinceScale = 2;
  do {
    if (checkNode == currentNode) return true;
    if (since >= sinceScale){
        checkNode = currentNode;
        since = 0;
        sinceScale = 2*sinceScale;
    }
    since++;
  } while (currentNode = currentNode.next());
  return false;
}

At last this was mentioned as well:

This solution is O(n) because sinceScale grows linearly with the number of calls to next(). Once sinceScale is greater than the size of the loop, another n calls to next() may be required to detect the loop.

  • Please elaborate on your problem. Your problem is still not clear to me, what is it that is not making sense? – Vizag May 27 '18 at 13:32
  • I have not understood anything about their approach including its explanation like Exactly how these _since_ and _sinceScale_ working and why are they doubling _sinceScale_ whenever _since_ is becoming greater than _sinceScale_. You can actually tell me whatever you have understood... that might also help me. – Vaishali Gupta May 27 '18 at 14:33

1 Answers1

1

This is Brent's cycle-finding algorithm. https://en.wikipedia.org/wiki/Cycle_detection#Brent%27s_algorithm

I like it better than Floyd's algorithm for most purposes. It does indeed work in O(N) time:

  • It takes O(N) steps to get currentNode into the looping part of the list.
  • It will then take O(N) more steps until since == sinceScale, and checkNode is set to currentNode
  • From that point forward, checkNode and currentNode are both in the loop. As sinceScale gets larger, the frequency at which checkNode is reset decreases. When it's big enough, checkNode will remain constant until currentNode goes all the way around the loop and the cycle is detected. Scaling sinceScale by 2 every time ensures that this happens in O(N) as well.

For finding cycles in a linked list, either Floyd's algorithm or Brent's algorithm work fine, but Brent's algorithm is more convenient in a lot of real-life situations when getting from the current state to the next state is expensive and it would be impractical to move the second "slow" pointer that Floyd's algorithm requires.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • Thanks for your explanation. It was quite helpful. Although i have not understood the entire thing but now that you have told me about this algorithm, i'll try to learn more about it. – Vaishali Gupta May 27 '18 at 15:59