> Имеет ли смысл начинать второй цикл с начала при поиске пары чисел в массиве (JavaScript)

Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Кодинг

Компании: ЭНИРАН

Стек: Node.js, JavaScript

> Пример ответа

Короткий ответ

Нет, если речь о поиске пары чисел с заданной суммой, второй цикл не нужно начинать с начала. Это приведёт к избыточным проверкам и квадратичной сложности O(n²) даже для отсортированного массива. Оптимальный подход - использовать два указателя (two pointers) на отсортированном массиве или хеш-таблицу для одного прохода. Второй цикл с начала имеет смысл только в наивном решении, когда важна простота, а не производительность.

Подход к решению

Для задачи "найти пару чисел, дающую заданную сумму" есть два основных подхода:

  1. Хеш-таблица (O(n)): проходим массив один раз, для каждого элемента проверяем, есть ли в map значение target - current. Если есть - пара найдена. Иначе добавляем текущий элемент в map.
  2. Два указателя (O(n log n)): сортируем массив, ставим левый указатель на начало, правый на конец. Сравниваем сумму: если меньше target - двигаем левый, если больше - правый. Второй цикл не нужен.

Наивный вариант с двумя вложенными циклами, где второй начинается с i + 1, допустим только для очень маленьких массивов или когда важна читаемость кода. Начинать второй цикл с нуля - грубая ошибка, так как пары (i, j) и (j, i) будут проверяться дважды.

Пример кода

JAVASCRIPT
// Оптимальное решение с хеш-таблицей
function findPairWithSum(arr, target) {
const seen = new Map();
for (let i = 0; i < arr.length; i++) {
const complement = target - arr[i];
if (seen.has(complement)) {
return [seen.get(complement), i];
}
seen.set(arr[i], i);
}
return null;
}
// Решение с двумя указателями (требует сортировки)
function findPairTwoPointers(arr, target) {
const sorted = [...arr].sort((a, b) => a - b);
let left = 0;
let right = sorted.length - 1;
while (left < right) {
const sum = sorted[left] + sorted[right];
if (sum === target) return [left, right];
if (sum < target) left++;
else right--;
}
return null;
}

Edge cases

  • Пустой массив или массив из одного элемента - возвращаем null.
  • Массив с отрицательными числами - оба подхода работают корректно.
  • Дубликаты значений: хеш-таблица вернёт первую пару, два указателя - тоже, но нужно быть осторожным с индексами после сортировки.
  • Если target равен удвоенному значению элемента, и этот элемент встречается дважды - хеш-таблица корректно найдёт второе вхождение, а два указателя - только если сортировка сохранит дубликаты.
  • Очень большие числа - используйте Number.isSafeInteger для проверки, если это критично.

Как отвечать на собеседовании

Начните с уточнения: "Речь идёт о поиске пары с заданной суммой?" Затем объясните trade-off между простотой и производительностью. Покажите, что понимаете, почему второй цикл с начала - плохая идея: лишние проверки, повторные пары, O(n²). Предложите два оптимальных решения, сравните их по памяти и времени. Если интервьюер попросит наивное решение - напишите его, но сразу укажите на недостатки. Обязательно спросите про ограничения: отсортирован ли массив, важны ли индексы или только значения.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание сложности алгоритмов и умение обосновать выбор.
  • Знание типичных паттернов: two pointers, hash map.
  • Умение задавать уточняющие вопросы перед написанием кода.
  • Внимание к edge cases (дубликаты, отрицательные числа, пустой массив).
  • Способность объяснить trade-off между временем и памятью.
  • Чистоту кода: обработка null, корректные индексы, читаемость.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью