Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: cyclic structure, linked list, Floyd's algorithm, cycle detection, tortoise and hare

Как определить количество элементов в циклической структуре без меток?

Этот вопрос проверяет умение работать с циклическими структурами данных, такими как связные списки с петлями, и знание алгоритмов для определения их размера, что важно для отладки и анализа данных.

Короткий ответ

Чтобы определить количество элементов в циклической структуре без меток, можно использовать алгоритм Флойда ("черепаха и заяц"). Сначала найдите точку встречи двух указателей, движущихся с разной скоростью, чтобы обнаружить цикл. Затем, остановив один указатель, подсчитайте, сколько шагов нужно второму, чтобы вернуться в ту же точку — это даст длину цикла. Наконец, чтобы найти общее количество элементов, включая хвост до цикла, можно сбросить один указатель в начало и двигать оба с одинаковой скоростью до встречи.

Длинный ответ

Циклические структуры данных, такие как связные списки с петлями, часто встречаются в программировании, и определение их размера (общего количества уникальных элементов) — нетривиальная задача, поскольку простой обход приведёт к бесконечному циклу. Алгоритм Флойда обнаружения цикла ("черепаха и заяц") предоставляет элегантное решение.

Обнаружение цикла и его длины

Алгоритм использует два указателя: "медленный" (движется на 1 шаг за итерацию) и "быстрый" (на 2 шага). Если в структуре есть цикл, они обязательно встретятся внутри него. После обнаружения встречи можно зафиксировать один указатель и подсчитать, сколько шагов потребуется второму, чтобы обойти цикл и вернуться в ту же точку — это даст длину цикла (L).

Определение общего размера структуры

Чтобы найти общее количество элементов (N), включая "хвост" до входа в цикл, нужно определить точку входа в цикл. После нахождения длины цикла сбросьте один указатель в начало структуры, а другой оставьте в точке встречи. Теперь двигайте оба указателя с одинаковой скоростью (по 1 шагу). Они встретятся как раз в точке входа в цикл. Зная длину хвоста (K) и длину цикла (L), общий размер N = K + L.

Пример кода на Python

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

def count_elements_in_cyclic_list(head):
    if not head:
        return 0
    # Шаг 1: Обнаружение цикла алгоритмом Флойда
    slow = fast = head
    has_cycle = False
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            has_cycle = True
            break
    # Если цикла нет, просто считаем элементы
    if not has_cycle:
        count = 0
        current = head
        while current:
            count += 1
            current = current.next
        return count
    # Шаг 2: Определение длины цикла (L)
    cycle_length = 1
    fast = slow.next
    while fast != slow:
        cycle_length += 1
        fast = fast.next
    # Шаг 3: Нахождение точки входа и длины хвоста (K)
    slow = head
    fast = head
    # Сдвигаем fast на L шагов вперёд
    for _ in range(cycle_length):
        fast = fast.next
    # Двигаем оба с одинаковой скоростью
    tail_length = 0
    while slow != fast:
        slow = slow.next
        fast = fast.next
        tail_length += 1
    # Общий размер: хвост + цикл
    return tail_length + cycle_length

# Пример использования
# Создаём список: 1 -> 2 -> 3 -> 4 -> 5 -> 3 (цикл к элементу 3)
node1 = Node(1); node2 = Node(2); node3 = Node(3); node4 = Node(4); node5 = Node(5)
node1.next = node2; node2.next = node3; node3.next = node4; node4.next = node5; node5.next = node3
print(count_elements_in_cyclic_list(node1))  # Вывод: 5 (элементы 1,2,3,4,5)

Этот подход эффективен по времени (O(N)) и памяти (O(1)), так как использует только два указателя. Он применяется при анализе структур данных, отладке алгоритмов и в задачах, связанных с графами.

Вывод: Алгоритм Флойда стоит применять, когда нужно проанализировать циклические структуры без дополнительной памяти, например, при работе со связными списками, графами или потоками данных, где возможны зацикливания.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    3

  • Сложность:

    6

Навыки

  • JavaScript

    JavaScript

  • C

    C

Ключевые слова

#cyclic structure

#linked list

#Floyd's algorithm

#cycle detection

#tortoise and hare

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.