Я собираюсь предвосхитить это тем фактом, что я не полностью разбираюсь в нотации Big O, поэтому, возможно, мои мысли об этом не верны.
Я случайно просматривал SO, когда натолкнулся на вопрос об обнаружении бесконечных циклов в связанных списках. Это указало мне на алгоритм здесь , известный как Черепаха и Кролик.
class Node {
Node next;
}
boolean isInInfiniteLoop(Node node) {
if (node == null) {
return false;
}
Node turtle = node; // slower moving node
Node rabbit = node.next; // faster moving node
while (rabbit != null) {
if (rabbit.equals(turtle)) {
// the faster moving node has caught up with the slower moving node
return true;
} else if (rabbit.next == null) {
// reached the end of list
return false;
} else {
turtle = turtle.next;
rabbit = rabbit.next.next;
}
}
// rabbit reached the end
return false;
}
В статье он упоминает, что это O (N). Из того, что я понимаю, O (N) означает, что скорость алгоритма растет линейно по отношению к количеству элементов в списке.
Однако, если я не смотрю на вещи неправильно, переменная кролика всегда пропускает 1 узел (так что он «быстрее»), что означает, что он может пропускать узел черепахи, таким образом, имея потенциал зацикливания вокруг бесконечный цикл 1 или более раз, прежде чем он станет тем же узлом, что и переменная turtle, что будет означать, что в худшем случае не O (N).
Я что-то упустил? Я думаю, что оптимизация может заключаться в том, чтобы проверить, если rabbit.Next.Equals(turtle)
также, но так как ни один из комментариев не указывают на это, поэтому мне интересно, если я что-то упустил.