Бинарный поиск

Базовый Algorithms
≈ 2 мин чтения

Зачем нужен бинарный поиск

Обычный поиск может проверять элементы один за другим. Но если данные уже упорядочены, этим порядком можно воспользоваться: после одной проверки отбросить сразу большую часть вариантов и продолжить поиск только там, где ответ ещё может находиться. На этой идее строится бинарный поиск.

Он полезен не только для вопроса «есть ли число в массиве». Та же схема помогает находить границы диапазонов, первую или последнюю подходящую позицию, работать со сдвинутыми отсортированными массивами и даже искать минимальное или максимальное значение, для которого выполняется некоторое условие.

Что входит в раздел

  • Основы бинарного поиска. Разберём идею деления области поиска пополам и условия, без которых этот подход не работает.
  • Поиск в отсортированном массиве. Соберём классический итеративный шаблон, который возвращает позицию найденного элемента.
  • Lower Bound и Upper Bound. Научимся искать не конкретное значение, а первую позицию относительно заданной границы.
  • Первая и последняя позиция. Используем поиск границ, когда одинаковое значение встречается несколько раз.
  • Циклически сдвинутый отсортированный массив. Увидим, как сохранить идею бинарного поиска, даже если привычный глобальный порядок нарушен сдвигом.
  • Бинарный поиск по ответу. Перенесём тот же принцип с индексов массива на пространство возможных ответов.

Главная мысль

Java
int mid = left + (right - left) / 2;

if (values[mid] < target) {
    left = mid + 1;
} else {
    right = mid;
}

Ключ здесь не в формуле середины, а в том, что после проверки середины можно доказанно исключить одну часть диапазона. В следующих темах мы постепенно научимся формулировать это доказательство для разных задач.