Бесплатная бета: 60 дней полного доступа, без карты.мест осталось: 84Зарегистрироваться бесплатно

Мы используем необходимые куки для работы сайта (вход и язык). Если ты согласишься, мы также загрузим Google Analytics, чтобы видеть, какие страницы читают, и Google reCAPTCHA для защиты форм обратной связи и сообщений об ошибке от спама. Политика конфиденциальности

Все паттерны

Бинарный поиск (массив)

Binary search (array)

O(log n)

Посмотрите на середину отсортированного отрезка и выбросьте половину, где ответа быть не может. Повторяйте до одного элемента.

Обновлено 17 окт. 2026 г.

Бинарный поиск (массив): как это работает?

Держите две границы, низ и верх, на отсортированном отрезке. Ответ, если он есть, лежит между ними.

Возьмите средний индекс этого отрезка. Сравните стоящее там значение с искомым.

При совпадении поиск закончен. Верните этот индекс.

Если среднее значение мало, цель лежит правее. Сдвиньте низ за середину.

Если оно велико, сдвиньте верх левее середины. В обоих случаях половина отрезка исчезает.

Цикл кончается, когда низ обогнал верх. Отрезок пуст, значит цели нет.

Источники: Википедия: Двоичный поиск, Документация Python (англ.): bisect

  1. lo=0 hi=5Ищем 7 в [1, 3, 5, 7, 9, 11]. Кандидатов шесть.
  2. mid=2, значение 55 меньше 7. Всё левее выбывает.
  3. lo=3 hi=5, mid=4, значение 99 больше 7. Всё правее выбывает.
  4. lo=3 hi=3, mid=3, значение 7Остался один кандидат, и он подходит.
  5. возврат 3Три сравнения на шесть элементов. Удвоение входа добавит одно.
Ищем 13 в отсортированном массиве, деля отрезок пополам
binarySearch([1, 3, 5, 7, 9, 11, 13, 15], 13)
arr (отсортирован)
1
3
5
7
9
11
13
15

lo

hi
target = 13lo = 0hi = 7mid = -return = ?

Ищем 13 в отсортированном массиве. lo и hi отмечают отрезок, где оно ещё может быть: сначала это весь массив.

Гонка скорости
Бинарный поиск против линейного просмотра по одним и тем же 48 отсортированным числам

Столбики: отсортированные числа. Бинарный поиск делит диапазон пополам при каждом сравнении, линейный просмотр читает их по одному.

Одна операция: одно сравнение с искомым числом. За каждый кадр все дорожки делают одинаковое число операций, поэтому медленная отстаёт.

Линейный просмотр O(n)
операций: 0
Бинарный поиск O(log n)
операций: 0

 

А если чисел больше

Операции для n чисел и примерное время при 100 миллионах простых операций в секунду. Это оценка по тому же счёту, а не замер.

n = 1 000
Линейный просмотр900 · меньше 1 мс
Бинарный поиск10 · меньше 1 мс
n = 100 000
Линейный просмотр90 тыс. · меньше 1 мс
Бинарный поиск16,6 · меньше 1 мс
n = 10 000 000
Линейный просмотр9 млн · 90 мс
Бинарный поиск23,3 · меньше 1 мс

Бинарный поиск (массив): шаблон кода

function binarySearch(arr, target) {
    let lo = 0, hi = arr.length - 1;
    while (lo <= hi) {
        const mid = (lo + hi) >> 1;
        if (arr[mid] === target) return mid;
        if (arr[mid] < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return -1;
}

Бинарный поиск (массив): разбор примера

Первая и последняя позиция значения

В отсортированном массиве одно значение может повторяться много раз. Верните первый и последний индекс цели.

Если значения нет, верните минус один дважды.

Запустите поиск дважды с разным правилом при совпадении.

Для первого индекса после совпадения двигайте верх влево. Для последнего двигайте низ вправо.

function searchRange(nums, target) {
    function bound(findFirst) {
        let lo = 0;
        let hi = nums.length - 1;
        let found = -1;

        while (lo <= hi) {
            const mid = lo + Math.floor((hi - lo) / 2); // cannot overflow

            if (nums[mid] === target) {
                found = mid;
                // a match is not the end: keep squeezing the chosen side
                if (findFirst) hi = mid - 1;
                else lo = mid + 1;
            } else if (nums[mid] < target) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }

        return found;
    }

    return [bound(true), bound(false)];
}

Бинарный поиск (массив): когда применять?

Паттерн «Бинарный поиск (массив)» нужен, когда в условии есть слова «отсортированный массив», «найти цель / первое или последнее вхождение» или «n до 1e6+ и ожидается O(log n)». Решение на нём обычно укладывается в O(log n).

  • отсортированный массив
  • найти цель / первое или последнее вхождение
  • n до 1e6+ и ожидается O(log n)
  • найти границу, где условие меняется
  • поиск во вращённом, но почти отсортированном массиве (с подвохом)

Слова в условии для всех паттернов собраны в одной таблице: шпаргалка по паттернам алгоритмов.

Бинарный поиск (массив): с чем путают?

Паттерн «Бинарный поиск (массив)» чаще всего путают с этими паттернами: Линейный поиск, Бинарный поиск во вращённом массиве, Бинарный поиск по ответу, Двоичное дерево поиска и Два указателя (с концов).

  • Линейный поиск (Linear search): Перебор читает каждый элемент, но порядка не требует. Бинарному поиску порядок нужен, зато он читает log n.
  • Бинарный поиск во вращённом массиве (Binary search on a rotated array): Поворот рвёт единый отсортированный кусок. Проверка сначала ищет отсортированную половину.
  • Бинарный поиск по ответу (Binary search on the answer): Там отрезок это множество возможных ответов, а не массив. Проверку вы пишете сами.
  • Двоичное дерево поиска (Binary search tree): Дерево делит пополам так же, но через указатели. Ещё оно допускает вставки, чего массив не умеет.
  • Два указателя (с концов) (Two pointers (opposite ends)): Там двигаются оба конца, и проверяемая пара меняется. Здесь за шаг двигается одна граница.

Бинарный поиск (массив): частые ошибки

  • Считают mid как lo плюс hi пополам

    Такая сумма может выйти за безопасный диапазон. Пишите lo плюс половина разрыва.

  • Двигают границу в mid, а не за него

    Отрезок перестаёт сжиматься, и цикл не кончается. Берите mid плюс один или mid минус один.

  • Смешивают два вида цикла

    При lo <= hi обе границы входят в отрезок. Смена одной границы без другой ломает инвариант.

  • Ищут в неотсортированных данных

    Сравнение считает, что слева от mid всё меньше. Без этого ответ тихо неверен.

Паттерн «Бинарный поиск (массив)» решает такие задачи с собеседований: Бинарный поиск, Позиция для вставки, Первая и последняя позиция элемента, Поиск пика, Квадратный корень, Поиск в двумерной матрице и Наименьшая буква больше заданной.

  • Бинарный поиск: Чистая форма на различных отсортированных значениях.
  • Позиция для вставки: Верните место, куда значение встало бы, если его нет.
  • Первая и последняя позиция элемента: Два поиска с противоположным правилом при совпадении.
  • Поиск пика: Сравнение идёт с соседом, а не с целью.
  • Квадратный корень: Отрезок это множество ответов, а не массив.
  • Поиск в двумерной матрице: Считайте всю сетку одним отсортированным списком.
  • Наименьшая буква больше заданной: Верхняя граница, которая заворачивается к началу.

Бинарный поиск (массив): сложность по времени и памяти

У паттерна «Бинарный поиск (массив)» целевая сложность O(log n).

n до 1e9 нормально, потому что log2 от 1e9 около 30. Время O(log n), память O(1).

Открыть бесплатный урок по этому паттерну