Is there a way to check if a single-linked list contains cycles for linear time without copying and modifying the list?
I thought we could try to sort this list topologically. If cannot there is somr cycle... But it seems it's not gonna work.
Is there a way to check if a single-linked list contains cycles for linear time without copying and modifying the list?
I thought we could try to sort this list topologically. If cannot there is somr cycle... But it seems it's not gonna work.
You can do it in constant space without altering the array.
The method is known as Floyd's cycle-finding algorithm. It is based on the idea of going through the list with two pointers moving at different speeds. Eventually, if and only if the list contains a cycle, the pointers will meet. Also, the algorithm finds the point where the loop starts. Check the provided link for more details.
As suggested in the comment, you can use fast and slow iterator solution.
Key insight:
The key insight in the algorithm is that, for any integers i ≥ μ and k ≥ 0, x(i) = x(i + kλ), where λ is the length of the loop to be found and μ is the index of the first element of the cycle. In particular, i = kλ ≥ μ, if and only if x(i) = x(2i). Thus, the algorithm only needs to check for repeated values of this special form, one twice as far from the start of the sequence as the other, to find a period ν of a repetition that is a multiple of λ. Once ν is found, the algorithm retraces the sequence from its start to find the first repeated value xμ in the sequence, using the fact that λ divides ν and therefore that x(μ) = x(μ + v). Finally, once the value of μ is known it is trivial to find the length λ of the shortest repeating cycle, by searching for the first position μ + λ for which x(μ + λ) = x(μ).
Reference Link : Floyd's Tortoise and Hare