How to find the beginning node of a loop in a given linked list ? Let’s call this the cycle point
So far, I’ve understand the following (using slow/fast pointer):
- Assume list has a non-looped part of size
k - slow moves k steps
- fast moves 2k steps
- fast is (2k – k)=
kstepsaheadof slow - slow is at the beginning of loop; also known as
Cycle point - fast is
(LOOP_LENGTH - k)stepsbehindfromCycle pointor slow pointer at this point - for each 1 step slow moves, fast moves 2 steps and gains on slow by 1 step.
- Thus, it would take fast
(LOOP_LENGTH - k)steps to meet slow and collide - This is the step I don’t understand:
At this collision point, both nodes will beksteps from the front of the loop. - Once the collision point is found, move one pointer to the head of list.
- Now move both pointers at the speed of 1 step / turn till the collide. The node at which they both meet is the beginning of the the loop and hence the
Cycle point
Can someone please explain me step 9 and after that ?
Thanks
EDIT:
One thing I’d like to point out is, once inside the loop, fast will never overtake slow pointer. They will collide. Here’s why: slow is at i and fast is assuming at i-1. when they move, slow=> i+1 and fast will be at i+1 too, hence collision. OR, slow is at i and fast is at i-2. next move, slow-> i+1; fast: i. next move, slow-> i+2, fast: i+2 and hence collision again. so fast will never be able to overtake slow, only collide once inside the loop!
Your 6. is wrong, the fast pointer is still k steps away from the slow pointer which is at the cycle point at that time; but better use ahead or behind instead of away. Plus,
kmay be smaller, bigger, or equal to theloop_length.So, the fast pointer is
ksteps ahead of a slow one when that’s reached the loop point which is, at your supposition,ksteps after the start. Now, measuring on a loop, the fast pointer isk % loop_lengthsteps ahead of the loop point. Right? Ifk = some_n * loop_length + r, the fast pointer isrsteps ahead of the loop point, which is to say,r := k % loop_lengthsteps ahead.But that means that the slow pointer is
loop_length - rsteps ahead of the fast one, along the loop. This is a loop after all. So afterloop_length - radditional steps the fast pointer will catch on to the slow one. For each step the slow pointer moves away, the fast moves closer in by two steps.So we don’t know
k, we don’t knowloop_lengthorr, we only knowm = k + loop_length - r = some_n * loop_length + r + loop_length - r = (some_n+1) * loop_length. The total number of stepsmuntil the two pointers’ meeting point, is a multiple of the loop length.So now we start over, with a new pointer at the start and the slow where it met the fast,
msteps ahead of the new. We move the new and the slow at equal speed, by 1 step at each time, and at the cycle point they shall meet – because when the new pointer has reached the cycle point, the second is stillmsteps ahead, which is to say,m % loop_length == 0steps ahead along the loop. That way we find out whatkis (we count our steps all the time), and the cycle point.And we find
loop_lengthby going along the loop one more time, until the two meet one more time.