简体   繁体   中英

Looking to understand the algorithm to find the start of a loop in a singly linked list

There's a really elegant solution to this problem here , but I don't understand the biggest part - why, after moving S back to the beginning of the list, are S and F the same distance from the loop start? He does some math to "prove" it, but it doesn't quite make sense to me. Any help in understanding this better would be much appreciated. Thanks!

To frame the problem, we assume that there is an n node loop starting m nodes past the start and that we are walking it with a slow pointer S (one node each step) and a fast pointer F (two nodes each step). For the sake of brevity, we assume that m < n , but it doesn't matter so much (just do some modular arithmetic).

The key is to realize that S and F will overlap at node n - m . The math done in the article is admittedly a little hard to follow, and doesn't seem to generalize to odd n . Not sure this will be much easier, but I'll try.

Suppose that S starts at the beginning of the loop and F starts k nodes past the start of the loop and we start walking the loop. At time step x , S will be x nodes past the start of the loop and F will be 2x + k nodes past the start of the loop. Of course, F will not overtake S until F has crossed the start of the loop, at which point we can equivalently describe it as being (2x + k) - n = 2x - (n - k) nodes past the start.

We now ask, "at what step x will S and F overlap?" That is simply when the position of S is equal to the position of F, so x = 2x - (n - k) , or (with some simple algebra), x = n - k . Thus, both pointers will be n - k nodes past the start of the loop.

Back to the original problem (both pointers start from the head of the list), by the time S hits the start (in m steps), F will have traveled 2m steps, and thus will be m nodes past the start of the loop ( 2m - m = m ). Replace k with m above and we see that when we continue the nodes will overlap when pointer F (and S) are n - m nodes past the start of the loop. Thus, if we move S back to the beginning, both F and S will take m steps to get back to the beginning of the loop.

Let me know if this helps.

  1. take 2 pointers (f and s).
  2. start both the pointers from the Link list head. Make f(faster) traverse twice the speed of s(slower) ie f will jump twice and s will jump once.
  3. check if they will meet.
  4. if they meet then make s point to the start of the link list and do not change the value of f (since f is now pointing to their meeting node)
  5. Now make both the pointer speed equal and make them move one node only.
  6. The point where they will meet will be the start of the loop. (to get this just draw a diagram or understand the above post.

Let me know if you dint get this. Will be happy to assist you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM