Алгоритм обнаружения цикла Флойда | Определение начальной точки цикла

32

Я ищу помощь в понимании алгоритма обнаружения цикла Флойда. Я прошел объяснение в Википедии ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Я могу видеть, как алгоритм обнаруживает цикл в O (N) времени. Однако я не могу представить себе тот факт, что как только указатели черепахи и зайца встречаются в первый раз, начало цикла можно определить, переместив указатель черепахи обратно, чтобы запустить, а затем переместив черепаху и зайца по одному шагу за раз. Точка, где они впервые встречаются, является началом цикла.

Может ли кто-нибудь помочь, предоставив объяснение, которое, я надеюсь, отличается от того, которое есть в Википедии, поскольку я не могу понять / представить его?

Анураг Капур
источник
3
Я нашел ответ на stackoverflow. Спасибо, если кто-то изучал это для меня. А для тех, кто, как я, хотел объяснения, обращайтесь по адресу : stackoverflow.com/questions/3952805/… Выбранный ответ на вопрос объясняет это!
Анураг Капур
Привет @Anurag. Просто для вашего сведения, я сделал пост в блоге об алгоритме «Черепаха и заяц» здесь
Кайл
Знаете ли вы, почему fastпеременная, или «заяц», должна двигаться вдвое быстрее, чем черепаха, а не впереди?
devdropper87
Красиво объяснено с программой: javabypatel.blogspot.in/2015/12/detect-loop-in-linked-list.html
Jayesh

Ответы:

47

Вы можете обратиться к «Обнаружение начала цикла в односвязном списке» , вот выдержка:

введите описание изображения здесь

Расстояние, пройденное slowPointerдо встречи знак равноИкс+Y

fastPointer знак равно(Икс+Y+Z)+Y

Так как fastPointerпутешествует с удвоенной скоростью slowPointer, и время постоянно для обоих, когда достигают места встречи. Итак, используя простое соотношение скорости, времени и расстояния ( slowPointerпройденное на половину расстояния):

2*расстояние(slowPointer)знак равнорасстояние(fastPointer)2(Икс+Y)знак равноИкс+2Y+Z2Икс+2Yзнак равноИкс+2Y+ZИксзнак равноZ

Следовательно, перемещаясь slowPointerк началу связанного списка, делая оба slowPointerи fastPointerперемещая один узел за раз, они оба имеют одинаковое расстояние для покрытия .

Они достигнут точки, где цикл начинается в связанном списке.

Старый Монах
источник
2
Здесь вы сделали предположение, что они встретятся после одного поворота. Могут быть случаи (когда цикл мал), где они могут встретиться после определенного нет. вращений.
Navjot Waraich
1
@JotWaraich изображение не является репрезентативным для всех случаев; логика, однако, все еще остается в силе
denis631
3
это самый простой ответ об этом алгоритме во всем Интернете
Marshall X
7

Я видел принятый ответ как доказательство и в других местах. Однако, хотя его легко уловить, это неверно. Что это доказывает

Иксзнак равноZ

То, что вы действительно хотите доказать, это (используя те же переменные, которые описаны в диаграмме в принятом ответе выше):

Zзнак равноИкс моd (Y+Z)

(Y+Z)L

Итак, что мы хотим доказать:

Zзнак равноИкс моd L

Или что z конгруэнтно х (по модулю L)

Следующее доказательство имеет больше смысла для меня:

Mзнак равноИкс+Y

2(Икс+Y)знак равноM+КLКИкс+YL

Икс+Yзнак равноКL

Иксзнак равноКL-Y

ИксLYMИкс+Y

l8Again
источник