There is this apparently standard approach to find if a linked list has a cycle and then return the node that is at the start of the cycle which is floy's algorithm with slow/fast pointers.
The code and the logic is clear except 1 thing.
The approach is based on the assumption that the node in the loop that the pointers will meet is exactly the same number of steps as from the head of the list till the start of the loop.
That part is what I don't get.
So if Slow and Fast both start at the head of the list, when Slow does k steps and reaches the start of the loop, Fast will have done 2k steps and is effectively k steps into the loop.
So fast is ahead of slow by k steps and behind of slow (which is at the start of the loop) N - k where N is the loop size.
Since at each step fast approaches slow and fast is behind slow by N - k nodes, fast will reach slow in N - k steps.
At this point, slow would have done N - k steps and will be in node N - k.
Fast would have done 2(N - k) steps and will be at node 2N - 2k + k = 2N - k (since fast was at node k).
Since this is a loop 2N - k = N - k and hence they meet at node N - k.
But why is N - k node k steps from the start of the loop?
What am I misunderstanding here?

- 3,845
- 3
- 22
- 47
-
Are you assuming the cycle starts at the beginning of the list? – rici May 29 '18 at 21:55
-
@rici:No. It can be anywhere in the list. – Jim May 29 '18 at 22:07
-
@rici: `A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> D` – Jim May 29 '18 at 22:09
2 Answers
Here is what you are missing.
Whenever both pointers are in the loop and the fast pointer is a multiple of the loop length ahead, the fast pointer has lapped the slow an integer number of times and they are in the same place. If you continued they would separate and will lap again. And again. And again.
The whole reason why the algorithm works is this lapping behavior.
The first time that they meet, it might be at a strict multiple of the cycle length. For example if you have a chain of 24 nodes leading into a cycle of length 7 then they will first meet after 28 steps.
EDIT I was explaining how the cycle detection worked, and not how the detection of the head worked. Here is an alternate explanation of that. In different words.
Suppose we have a chain of i
nodes leading to a loop of length j
. We initially run fast+slow pointers and they meet. In order to meet, the fast has to have gone some integer number of times more around the loop than the slow one did. So they meet after k*j
steps.
At this point the slow pointer traveled k*j
steps total, of which i
steps were getting to the loop, so it has traveled k*j-i
steps inside of the loop.
Now we put the fast pointer at the start, and advance them at the same rate. In another i
steps the pointer at the start has reached the loop. The slow pointer, meanwhile, had previously traveled k*j-i
steps inside of the loop, and now travelled another i
steps for k*j
steps inside of the loop. Since k*j
is a multiple of the loop length, it is also back at the beginning and they meet again.

- 43,296
- 3
- 59
- 88
-
My question is different. I understand that they will meet after N - k steps but what I don't understand is why the meeting point is k steps before the start of the loop and also k steps is the distance from head to the start of the loop – Jim May 30 '18 at 07:36
-
@Jim I believe that you are confusing yourself. What matters is not exactly where they meet - though the where is easy enough to figure out - but that they absolutely must. Once they are both into the loop, with one going faster, the faster one will eventually catch up and they meet. – btilly May 30 '18 at 15:33
-
My question is about the question: find the start of a loop in a linked list. The solution mentioned in my post takes for granted that the node that slow and fast meet is the same number of steps from the start of the loop as the head of the list to the start of the loop. Hence by keeping one pointer in the meeting point and moving the other to the head of the list and move both one step at a time the node they meet in this iteration is the start of the loop. An example online http://umairsaeed.com/blog/2011/06/23/finding-the-start-of-a-loop-in-a-circular-linked-list/ – Jim May 30 '18 at 17:34
-
@Jim Ah. I was answering the wrong question. I added an answer of the other half. – btilly May 30 '18 at 18:27
-
1) If they meet at `k*j` steps which means a multiple of the loop why does this number include `i`? Seems to me that after `i` steps and when getting to the start of the loop then the slow meets fast after `k*j` steps. 2) Except my previous question about `i` what you describe answers what I am asking but I don't understand where is the error in the reasoning I describe in my post. It seems that the `N - k` that I have is the same as the `k*j` that you say but expressing it like that shows the k steps needed. But `N - k - k` gives N and so I am not clear what is the faulty part in my reasoning – Jim May 30 '18 at 18:40
-
@Jim They can only meet at `k*j` steps because that is when the fast loop has gone an integer number of times more around than the slow one. `i` comes into it because that is how many steps are needed on the way into the loop. – btilly May 30 '18 at 19:51
-
-
No. The slow pointer will have gone `k*j` steps from the starting pointer. The fast pointer has gone `2k*j` steps from the starting pointer. Therefore the fast has gone around the loop an extra `j` times. And the slow went `i` steps to get to the loop, and only `k*j - i` steps inside of the loop. Write down some small examples and trace them out to verify. – btilly May 30 '18 at 20:24
Let me give you another way to look at for this problem , and in the end, you might get your answer too.
Variables used for explanation:
- N - total number of node links in linkedlist .
- C - distance from head to the start point of loop
- Y - distance from the starting of loop to the meeting point.
- K - distance from the meeting point to the start of the loop.
So, we can drive some conclusions from these variables.
- N = C + Y + K
- Distance covered by slow pointer - Ds = C + Y
- Distance covered by fast pointer - Df = N + Y
Here ,
- N = 12
- C = 2
- Both Pointers will meet at node number 11, so Y = 8
- K = 2
Since we know that fast pointer is 2 times faster than slow pointer, so Df = 2 * Ds
Using the relation between Df and Ds , and putting there values from above
N + Y = 2 * ( C + Y )
N + Y = 2*C + 2*Y
N = 2*C + Y
Using N's another relation ,
C + Y + K = 2*C + Y
K = C
This concludes that the distance between head and starting of loop equals to the distance between meeting point node and starting of the loop .
Try to understand this and always try to simplify the task by breaking it into smaller chunks .
Hope this will help.
Keep asking , keep growing :)

- 136
- 6