Получить доступ

Как работает бинарный поиск?

JuniorПоиск
Ещё спрашивают так:
  • Какая сложность у бинарного поиска?
  • Как найти первое вхождение элемента в отсортированном массиве?
  • Что такое бинарный поиск по ответу?
Коротко

В отсортированном массиве сравниваем искомое с серединой и отбрасываем половину, где его быть не может: O(log n) шагов.

  • Миллион элементов — не больше 20 сравнений, миллиард — 30
  • Типичные ошибки: границы, бесконечный цикл, переполнение (lo + hi) / 2 в языках с фиксированными целыми

А ещё Обобщение — поиск по ответу: на монотонной функции найти первую точку, где условие стало истинным

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Попробуйте сами

Бинарный поиск против линейного

Подробно

Условие — данные упорядочены. Держим границы lo и hi, внутри которых может быть искомое. Смотрим на средний элемент:

  • равен искомому — нашли;
  • меньше — искомое правее, lo = mid + 1;
  • больше — левее, hi = mid - 1.

Каждый шаг уменьшает область вдвое, поэтому шагов не больше log₂ n + 1. Для сравнения: линейный поиск в худшем случае смотрит все n элементов.

Частые ошибки:

  • неверные границы и условие цикла (< против <=), из-за чего пропускается последний элемент или цикл не заканчивается;
  • в языках с переполнением целых — (lo + hi) / 2 может переполниться; безопасно lo + (hi - lo) / 2;
  • поиск в неотсортированных данных.

Варианты: найти первое или последнее вхождение (lower bound / upper bound — не останавливаться при равенстве, а сдвигать границу), найти место вставки (bisect в Python). Поиск по ответу — когда есть монотонное условие: «минимальная пропускная способность, при которой всё успеем», «первая сломанная версия» (git bisect).

Пример

def lower_bound(a, target):
    """Первый индекс i, где a[i] >= target (или len(a))."""
    lo, hi = 0, len(a)
    while lo < hi:
        mid = (lo + hi) // 2
        if a[mid] < target:
            lo = mid + 1
        else:
            hi = mid
    return lo

a = [1, 3, 3, 3, 7, 9]
lower_bound(a, 3)   # 1 — первое вхождение
lower_bound(a, 4)   # 4 — место вставки

Что хотят услышать

  • Условие отсортированности и идея деления пополам.
  • Сложность O(log n) и интуиция, сколько это шагов.
  • Рабочий код без ошибок в границах.
  • Варианты: первое вхождение, поиск по ответу — плюс.

Частые ошибки

  • Бесконечный цикл из-за lo = mid при lo < hi с округлением вниз.
  • Применять к неотсортированным данным.

Что спросят дальше

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем