ENIGMA AI
ENIGMA AI

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

встречается 1× middle general

Как ответить

Этот вопрос про типичную логику алгоритма с двумя указателями на отсортированном массиве, например, для поиска пары с заданной суммой. Суть в том, что мы держим инвариант: левый указатель (L) всегда строго меньше правого (R), а оба сдвигаются в зависимости от того, больше или меньше текущая сумма цели.

Кейс, когда сдвигается левый указатель — это ситуация, когда nums[L] + nums[R] < target. Поскольку массив отсортирован по возрастанию, единственный способ увеличить сумму — сдвинуть L вправо (увеличить левое слагаемое). Так мы не пропустим потенциально подходящую пару, потому что любые пары с текущим L и любым меньшим R уже дали бы ещё меньшую сумму (ведь все элементы слева от R не больше текущего).

while L < R:  
    if nums[L] + nums[R] == target:  
        # нашли пару  
    elif nums[L] + nums[R] < target:  
        L += 1          # сдвиг левого  
    else:  
        R -= 1          # сдвиг правого

Кейс, когда сдвигается правый указатель — противоположный: nums[L] + nums[R] > target. Здесь сумма слишком велика, и чтобы её уменьшить, нужно сдвинуть R влево (уменьшить правое слагаемое). Это корректно, потому что правая сторона массива содержит бóльшие числа, и любая пара с текущим R и любым L правее текущего даст ещё бóльшую сумму.

Важные нюансы для middle-разработчика:

  • Инвариант: L всегда увеличивается, R всегда уменьшается, что гарантирует завершение цикла за O(n) без пропуска пар — при условии, что массив отсортирован.
  • Граничный случай «равно»: после нахождения цели можно сдвинуть оба указателя (L++, R--), если нужно найти все уникальные пары; иначе достаточно остановиться. Если требуется учитывать дубликаты, нужно дополнительно пропускать одинаковые значения.
  • Бесконечный цикл: если не менять условие L < R и не сдвигать указатели при равенстве, цикл зациклится. При сдвиге всегда меняется только один указатель за итерацию, поэтому цикл корректен.
  • Пример ошибки: новички иногда пытаются сдвигать оба указателя, когда сумма меньше цели, думая «увеличим левый и уменьшим правый». Но это ломает логику — мы можем пропустить пару (L, R-1) или (L+1, R). Правильный сдвиг только одного указателя сохраняет все возможности.

Таким образом, ответ сводится к простому правилу: при < меньше цели — двигаем левый, при > цели — двигаем правый. Конкретный выбор диктуется направлением изменения суммы и монотонностью массива.

Ключевые тезисы

  • Левый указатель сдвигается, когда текущая сумма меньше целевой, чтобы увеличить сумму за счёт большего элемента слева.
  • Правый указатель сдвигается, когда сумма больше цели, чтобы уменьшить сумму за счёт меньшего элемента справа.
  • Инвариант: L < R, и на каждой итерации сдвигается ровно один указатель, что гарантирует O(n) и корректность.
  • При нахождении цели (nums[L] + nums[R] == target) нужно решить, останавливаться или сдвигать оба, в зависимости от задачи (поиск всех пар или одной).
  • Дубликаты требуют дополнительных циклов пропуска одинаковых значений, иначе возможны повторные пары.

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

  • — Как изменится алгоритм, если массив не отсортирован? Какие альтернативы?
  • — Как адаптировать логику для поиска трёх чисел, сумма которых равна target (three sum)?
  • — Что будет, если мы случайно сдвинем левый указатель при сумме больше цели? Какая пара будет потеряна?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение