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

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

Все паттерны

Два указателя (с концов)

Two pointers (opposite ends)

O(n)

Два индекса стартуют по краям отсортированного массива и идут навстречу. Каждый шаг двигает ту сторону, что мешает ответу.

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

Два указателя (с концов): как это работает?

Один индекс стоит на первой ячейке, другой на последней. Вместе они задают кандидата на ответ.

Прочитайте значения на обоих концах и сложите их. Получится сумма, ширина или пара для сравнения.

Сравните результат с целью. Сравнение говорит, какой конец мешает.

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

Если она велика, сдвиньте правый индекс влево. Это единственный ход, который её уменьшит.

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

Источники: Wikipedia (англ.): 3SUM

  1. [2, 4, 5, 8, 11] lo=0 hi=4Цель равна 12. Указатели стартуют по краям.
  2. 2 + 11 = 13Сумма на единицу больше цели. Уменьшить её может только правый конец.
  3. [2, 4, 5, 8, 11] lo=0 hi=3Теперь 2 плюс 8 это 10, и этого мало. Увеличить может только левый конец.
  4. [2, 4, 5, 8, 11] lo=1 hi=3Теперь 4 плюс 8 это 12. Цель достигнута точно.
  5. ответ = [1, 3]Три сравнения на пять элементов. Ничего не прочитано дважды.
Пара с суммой 14 в отсортированном массиве
twoPointers([1, 2, 4, 6, 8, 11, 15], 14)
arr (отсортирован)
1
2
4
6
8
11
15

lo

hi
target = 14sum = -return = ?

Ищем два числа с суммой 14. Массив отсортирован, поэтому lo стоит на самом маленьком числе, а hi на самом большом.

Гонка скорости
Два вложенных цикла и два указателя ищут пару с заданной суммой в одних и тех же 40 отсортированных числах

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

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

Два вложенных цикла O(n²)
операций: 0
Два указателя O(n)
операций: 0

 

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

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

n = 1 000
Два вложенных цикла455 тыс. · 4,5 мс
Два указателя850 · меньше 1 мс
n = 100 000
Два вложенных цикла4,6 млрд · 46 с
Два указателя85 тыс. · меньше 1 мс
n = 10 000 000
Два вложенных цикла45,5 трлн · 5,3 дн.
Два указателя8,5 млн · 85 мс

Два указателя (с концов): шаблон кода

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

Два указателя (с концов): разбор примера

Контейнер с наибольшей водой

Каждое число это высота вертикальной линии на графике. Выберите две линии, между которыми поместится больше всего воды.

Площадь равна меньшей из линий, умноженной на расстояние между ними.

Начните с самой широкой пары, по линии на каждом краю.

Сдвигать более высокую линию бессмысленно: площадь ограничена низкой. Значит двигайте низкую и запоминайте лучшую площадь.

function maxArea(height) {
    let lo = 0;
    let hi = height.length - 1;
    let best = 0;

    while (lo < hi) {
        const area = Math.min(height[lo], height[hi]) * (hi - lo);
        best = Math.max(best, area);

        // the shorter side caps the area, so it is the only one worth moving
        if (height[lo] < height[hi]) lo++;
        else hi--;
    }

    return best;
}

Два указателя (с концов): когда применять?

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

  • отсортированный массив (или можно отсортировать)
  • найти пару/тройку с заданной суммой
  • сжать с обоих концов (контейнер, площадь)
  • проверка палиндрома

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

Два указателя (с концов): с чем путают?

Паттерн «Два указателя (с концов)» чаще всего путают с этими паттернами: Скользящее окно (переменное), Хеш-множество / словарь, Два указателя (в одну сторону) и Бинарный поиск (массив).

  • Скользящее окно (переменное) (Sliding window (variable)): Окно хранит живой отрезок, и оба конца идут вперёд. Эти указатели стартуют врозь и сходятся.
  • Хеш-множество / словарь (Hash set / map): Хеш находит дополнение в неотсортированных данных ценой O(n) памяти. Указателям нужен порядок, но не память.
  • Два указателя (в одну сторону) (Two pointers (same direction)): Там оба индекса идут вперёд: один читает, другой пишет. Здесь они сближаются с разных концов.
  • Бинарный поиск (массив) (Binary search (array)): Бинарный поиск ищет одну фиксированную цель и делит отрезок пополам. Здесь сравниваемая пара меняется каждый шаг.

Два указателя (с концов): частые ошибки

  • Забывают, что вход обязан быть отсортирован

    Весь приём держится на порядке. На неотсортированных данных сравнение указывает не туда.

  • Пишут lo <= hi

    При lo <= hi индекс составит пару сам с собой. Для пары разных элементов нужно lo < hi.

  • Двигают оба конца за один шаг

    Тогда верная пара может быть пропущена без проверки. Двигайте ровно один конец за шаг.

  • Выдают одну тройку дважды

    После совпадения пропускайте равные значения с обеих сторон. Иначе дубликаты вернутся как разные ответы.

Паттерн «Два указателя (с концов)» решает такие задачи с собеседований: Сумма двух II (отсортированный вход), Сумма трёх, Контейнер с наибольшей водой, Проверка палиндрома, Сбор дождевой воды, Сортировка цветов и Квадраты отсортированного массива.

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

Два указателя (с концов): сложность по времени и памяти

У паттерна «Два указателя (с концов)» целевая сложность O(n).

n до 1e6 на отсортированных данных даёт O(n). Каждый указатель делает не больше n шагов, память O(1).

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