← Назад к вопросам

Two Sum - найти два числа с заданной суммой

1.3 Junior🔥 231 комментариев
#Коллекции#Основы Java

Условие

Дан массив целых чисел nums и целое число target. Верните индексы двух чисел, сумма которых равна target.

Можно предположить, что каждый вход имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды.

Примеры

Пример 1:

  • Вход: nums = [2, 7, 11, 15], target = 9
  • Выход: [0, 1] (потому что nums[0] + nums[1] = 2 + 7 = 9)

Пример 2:

  • Вход: nums = [3, 2, 4], target = 6
  • Выход: [1, 2]

Требования

  • Решите задачу за O(n) используя HashMap
  • Обработайте случаи с отрицательными числами
  • Можете вернуть ответ в любом порядке

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Two Sum: нахождение двух чисел с заданной суммой

Суть задачи

Это классическая задача на хеширование и поиск. Нужно найти два элемента массива, которые в сумме дают целевое число, и вернуть их индексы.

Подходы решения

1. Наивный подход — перебор (O(n²))

public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] == target) {
                return new int[]{i, j};
            }
        }
    }
    return new int[]{};  // нет решения
}

Сложность: O(n²) — очень медленно при больших массивах.

2. Оптимальный подход — HashMap (O(n)) ✓

Идея: Проходим массив один раз. Для каждого числа проверяем, есть ли в HashMap число, которое в сумме с текущим даст target.

public int[] twoSum(int[] nums, int target) {
    // Ключ — число, значение — его индекс
    Map<Integer, Integer> numMap = new HashMap<>();
    
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];  // число, которое нам нужно найти
        
        // Проверяем, есть ли искомое число в HashMap
        if (numMap.containsKey(complement)) {
            return new int[]{numMap.get(complement), i};
        }
        
        // Добавляем текущее число в HashMap
        numMap.put(nums[i], i);
    }
    
    return new int[]{};  // нет решения
}

Сложность: O(n) время, O(n) память.

Пошаговый пример

nums = [2, 7, 11, 15], target = 9

Шаг 1: i=0, nums[0]=2
  complement = 9 - 2 = 7
  numMap пусто, 7 не найдено
  numMap = {2 → 0}

Шаг 2: i=1, nums[1]=7
  complement = 9 - 7 = 2
  numMap содержит 2! Индекс: 0
  ОТВЕТ: [0, 1]

Обработка отрицательных чисел

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> numMap = new HashMap<>();
    
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        
        if (numMap.containsKey(complement)) {
            return new int[]{numMap.get(complement), i};
        }
        
        numMap.put(nums[i], i);
    }
    
    return new int[]{};
}

// Пример с отрицательными числами:
// nums = [-3, 4, 3, 90], target = 0
// Шаг 1: nums[0]=-3, complement=0-(-3)=3, не найдено, numMap={-3→0}
// Шаг 2: nums[1]=4, complement=0-4=-4, не найдено, numMap={-3→0, 4→1}
// Шаг 3: nums[2]=3, complement=0-3=-3, НАЙДЕНО! ответ=[0,2]

Тестирование

public class TwoSumTest {
    private TwoSum solution = new TwoSum();
    
    @Test
    public void testBasicCase() {
        int[] nums = {2, 7, 11, 15};
        int[] result = solution.twoSum(nums, 9);
        assertArrayEquals(new int[]{0, 1}, result);
    }
    
    @Test
    public void testWithNegativeNumbers() {
        int[] nums = {-3, 4, 3, 90};
        int[] result = solution.twoSum(nums, 0);
        assertArrayEquals(new int[]{0, 2}, result);
    }
    
    @Test
    public void testSecondExample() {
        int[] nums = {3, 2, 4};
        int[] result = solution.twoSum(nums, 6);
        assertArrayEquals(new int[]{1, 2}, result);
    }
    
    @Test
    public void testLargeNumbers() {
        int[] nums = {1000000, 2000000, -1999999};
        int[] result = solution.twoSum(nums, 1);
        assertArrayEquals(new int[]{0, 2}, result);
    }
}

Почему HashMap лучше сортировки

Сортировка (O(n log n)):

  • Медленнее, чем HashMap
  • После сортировки индексы теряются, нужна доп. работа для их восстановления
  • Модифицирует исходный массив

HashMap (O(n)):

  • Одна итерация по массиву
  • Сохраняет индексы
  • Не модифицирует исходный массив
  • Работает с отрицательными числами из коробки

Сложности

ПодходВремяПамятьПримечание
ПереборO(n²)O(1)Очень медленно
HashMapO(n)O(n)Оптимально
Сортировка + двуказателиO(n log n)O(1)Медленнее HashMap

Вывод

HashMap подход — это классическое решение задачи Two Sum. Оно работает за один проход по массиву, обрабатывает отрицательные числа и любые целые значения. При интервью это именно то решение, которое хотят услышать.

Two Sum - найти два числа с заданной суммой | PrepBro