Это алгоритм поиска цикла Брента.https://en.wikipedia.org/wiki/Cycle_detection#Brent%27s_algorithm
Мне нравится больше, чем алгоритм Флойда для большинства целей.Это действительно работает за O (N) время:
- Требуется O (N) шагов, чтобы получить
currentNode
в циклической части списка. - ЗатемO (N) больше шагов до
since == sinceScale
, а checkNode
установлено на currentNode
- С этого момента
checkNode
и currentNode
оба находятся в цикле,Когда sinceScale
становится больше, частота, с которой checkNode
сбрасывается, уменьшается.Когда он достаточно большой, checkNode
будет оставаться постоянным до тех пор, пока currentNode
не пройдет весь цикл и не будет обнаружен цикл.Масштабирование sinceScale
на 2 каждый раз гарантирует, что это также происходит в O (N).
Для поиска циклов в связанном списке, либо алгоритм Флойда, либо алгоритм Брента работают нормально, но алгоритм Брентаудобнее во многих реальных ситуациях, когда переход из текущего состояния в следующее состояние дорог, и было бы нецелесообразно перемещать второй «медленный» указатель, который требует алгоритм Флойда.