← Назад к вопросам
Две суммы
2.0 Middle🔥 171 комментариев
#Теория тестирования
Условие
Дан массив чисел и целевое значение. Найдите индексы двух чисел, сумма которых равна целевому значению.
Пример
Вход: [2, 7, 11, 15], target = 9 Выход: [0, 1] (потому что 2 + 7 = 9)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Понимание задачи
Найти индексы двух чисел в массиве, сумма которых равна целевому значению. Каждый элемент используется только один раз, индексы должны отличаться.
Два подхода
1. Хеш-таблица (оптимальный)
- Проходим по массиву один раз
- Для каждого числа проверяем: есть ли complement = target - current_num
- Сохраняем число и его индекс в словаре
- Временная сложность: O(n), Память: O(n)
2. Два указателя (для отсортированного массива)
- Левый указатель в начале, правый в конце
- Двигаем указатели в зависимости от суммы
- Временная сложность: O(n log n), Память: O(1)
Реализация
def two_sum_hash(nums: list[int], target: int) -> list[int]:
"""Найти индексы двух чисел, сумма которых равна target"""
seen = {} # {число: индекс}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return [] # Не найдено
def two_sum_two_pointers(nums: list[int], target: int) -> list[int]:
"""Два указателя (для отсортированного массива)"""
nums_with_idx = [(num, i) for i, num in enumerate(nums)]
nums_with_idx.sort()
left, right = 0, len(nums_with_idx) - 1
while left < right:
current_sum = nums_with_idx[left][0] + nums_with_idx[right][0]
if current_sum == target:
return [nums_with_idx[left][1], nums_with_idx[right][1]]
elif current_sum < target:
left += 1
else:
right -= 1
return []
Комплексные тесты
import pytest
class TestTwoSum:
"""Набор тестов для поиска двух чисел с заданной суммой"""
@pytest.mark.parametrize("nums,target,expected", [
([2, 7, 11, 15], 9, [0, 1]),
([3, 2, 4], 6, [1, 2]),
([3, 3], 6, [0, 1]),
([1, 2, 3, 4, 5], 9, [3, 4]),
([10, 1, 2, 7, 11, 15], 9, [0, 2]),
([-1, -2, -3, 5, 10], 8, [3, 4]),
])
def test_two_sum_hash(self, nums, target, expected):
"""Тест метода хеш-таблицы"""
result = two_sum_hash(nums, target)
assert nums[result[0]] + nums[result[1]] == target
def test_negative_numbers(self):
"""Отрицательные числа"""
nums = [-10, -5, 0, 5, 10]
result = two_sum_hash(nums, 0)
assert nums[result[0]] + nums[result[1]] == 0
def test_zero_target(self):
"""Целевое значение ноль"""
nums = [0, 0, 1, 2]
result = two_sum_hash(nums, 0)
assert result == [0, 1]
def test_large_numbers(self):
"""Большие числа"""
nums = [1000000, 2000000, 3000000]
result = two_sum_hash(nums, 4000000)
assert nums[result[0]] + nums[result[1]] == 4000000
def test_no_solution(self):
"""Нет решения"""
nums = [1, 2, 3]
result = two_sum_hash(nums, 10)
assert result == []
def test_single_pair(self):
"""Только одна пара"""
nums = [5, 5]
result = two_sum_hash(nums, 10)
assert result == [0, 1]
def test_duplicate_values(self):
"""Дублирующиеся значения"""
nums = [1, 1, 1, 1, 2]
result = two_sum_hash(nums, 3)
assert nums[result[0]] + nums[result[1]] == 3
def test_two_sum_two_pointers(self):
"""Тест метода двух указателей"""
nums = [2, 7, 11, 15]
result = two_sum_two_pointers(nums, 9)
assert nums[result[0]] + nums[result[1]] == 9
Ключевые аспекты
- Хеш-таблица: O(n) время, O(n) память — идеально для большинства случаев
- Два указателя: требует сортировки, лучше для памяти
- Граничные случаи: дубликаты, отрицательные числа, большие значения
- Ограничения: каждый элемент используется один раз, индексы разные