Two sum
Описание
Для заданого массива целых чисел nums и целого числа target необходимо вернуть два индекса в nums. Сумма чисел по этим индексам должна образовывать число target.
Гарантируется, что при любых тестовых данных есть только одно решение, оба числа могут быть одинаковыми, но их индексы будут разными.
Ответ можно вернуть в любом порядке.
Пример 1:
Входные данные: nums = [2, 7, 11, 15], target = 9
Выходные данные: [0, 1]
Объяснение: Поскольку nums[0] + nums[7] == 9, мы вернули [0, 1]
Пример 2:
Входные данные: nums = [3, 2, 4], target = 6
Выходные данные: [1, 2]
Пример 3:
Входные данные: nums = [3, 3], target = 6
Выходные данные: [0, 1]
Идея решения
Решение в лоб для данного примера будет представлять проверку всех возможных комбинаций. Берём первое число в массиве и ищем, есть ли в массиве число равное разности target и текущему числу. В данном случае решение не будет эффективным, однако его можно взять за основу и ускорить используя хэш-таблицу.
Алгоритм решения
Можно решить это задание эффективно, всего за один проход. Нам необходимо вернуть индексы тех значений, которые в сумме дают target. Мы можем хранить вместо самого значения необходимую ему пару. Пример: Если мы встретили с индексом index = 0 число num = 7, а наш target = 10 то мы можем сохранить эту информацию в паре target - num: index и встретив число num = target - num в следующий раз нам необходимо будет вернуть два индекса, текущий индекс числа и сохранёный индекс его пары.
Таким образом наш алгоритм выглядит так:
1. создаём хэш-таблицу для хранения пар target - num: index 
2. итерируем наш список чисел nums сохраняя идекс текущего числа и получая подходящее число(которое в сумме с текущим даёт target)
3. если мы уже встречали такое подходящее число, то возвращаем индекс текущего числа и сохранёный инедкс подходящего числа
4. добавляем пару подходящего числа и текущего индекса в хэш-таблицу
Сложность
- По времени: \(O(N)\) n = len(nums)
Сложность по времени является линейной и определяется количеством чисел во входном массиве. При этом, только в худшем случае, когда второе искомое число является последним числом массива, будет необходимо перебрать весь массив.
Скорость поиска в хэш-таблицах O(1), так что поиск эллемента не замедляет алгоритм.
- По памяти: \(O(N)\) n = len(nums)
Для реализации алгоритма нам необходимо сохранить, в худшем случае, все эллементы входного массива. Таким образом сложность по памяти так же линейная и определяется количеством эллементов входящего массива.
Код решения:
use std::collections::{HashSet, HashMap};
impl Solution {
    pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
        let mut stack = HashMap::new();
        for (index, number) in nums.iter().enumerate() {
            let compliment = target - number;
            if let Some(&i) = stack.get(&compliment) {
                return vec![i as i32, index as i32];
            }
            stack.insert(*number, index);
        }
        unreachable!()
    }
}