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– Vizag2018年05月27日 13:32:39 +00:00Commented May 27, 2018 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– Vaishali Gupta2018年05月27日 14:33:11 +00:00Commented May 27, 2018 at 14:33
1 Answer 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
currentNodeinto the looping part of the list. - It will then take O(N) more steps until
since == sinceScale, andcheckNodeis set tocurrentNode - From that point forward,
checkNodeandcurrentNodeare both in the loop. AssinceScalegets larger, the frequency at whichcheckNodeis reset decreases. When it's big enough,checkNodewill remain constant untilcurrentNodegoes all the way around the loop and the cycle is detected. ScalingsinceScaleby 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.
1 Comment
Explore related questions
See similar questions with these tags.