Вот то, что вам не хватает.
Всякий раз, когда оба указателя находятся в цикле, а быстрый указатель кратен длине цикла вперед, быстрый указатель перекрывает медленное целое число раз, и онинаходятся в том же месте.Если вы продолжите, они разойдутся и снова упадут.И опять.И снова.
Вся причина, по которой работает алгоритм, заключается в этом притирочном поведении.
В первый раз, когда они встречаются, он может быть строго кратным длине цикла.Например, если у вас есть цепочка из 24 узлов, ведущих к циклу длиной 7, они сначала встретятся после 28 шагов.
РЕДАКТИРОВАТЬ Я объяснял, как работает обнаружение цикла, а некак работает обнаружение головы.Вот альтернативное объяснение этого.Другими словами.
Предположим, у нас есть цепочка из i
узлов, ведущих к петле длиной j
.Мы изначально бегаем быстро + медленные указатели, и они встречаются.Для того, чтобы встретиться, пост должен обходиться в цикле в целое число раз больше, чем медленный.Таким образом, они встречаются после k*j
шагов.
В этот момент медленный указатель прошел всего k*j
шагов, из которых i
шагов достигло петли, поэтому он прошел k*j-i
шагов внутрицикл.
Теперь мы помещаем быстрый указатель в начало и продвигаем их с той же скоростью.В других i
шагах указатель в начале достиг петли.Тем временем медленный указатель ранее проходил k*j-i
шагов внутри цикла, а теперь прошел еще i
шагов для k*j
шагов внутри цикла.Поскольку k*j
кратно длине цикла, оно также возвращается в начало, и они встречаются снова.