Site icon AppTractor

Задачи с собеседований: Leetcode — Сумма двух

Задача

Дан массив целых чисел nums и целое число target, нужно вернуть индексы двух чисел из массива, которые в сумме образуют target.

Каждый массив точно будет иметь ровно одно решение и нельзя использовать один и тот же элемент дважды.

Вы можете вернуть ответ в любом порядке.

Сумма двух на Leetcode: https://leetcode.com/problems/two-sum/

Решение

Первое приходящее на ум решение — сделать два вложенных цикла, в которых перебирать массив, поочередно складывая числа и сравнивая получившееся с целевым значением.

Вот мое решение:

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {    

       var resultA = [Int]()

       outerLoop: for i in 0...nums.count - 2 {
            for j in (i+1)...nums.count - 1 {
                // Поиск суммы
                if ((nums[i] + nums[j]) == target) {

                    resultA.append(i)
                    resultA.append(j)

                    break outerLoop
                }
            }
        }               
        return resultA
    }
}

Лучший результат на Leetcode:

Неплохо, но, очевидно, по скорости где то есть возможности для улучшения.

Что интересного из решения я узнал:

Другое решение

Очевидно, судя по материкам решения, существует другой подход. Честное гугление показало, что можно сделать так:

  1. Сначала хэшировать весь массив, определив позиции для каждого числа.
  2. Потом один раз перебрать массив, ища в хэшированном массиве разницу между текущим элементом и target.

В качестве структуры хеша я использовал словарь (Dictionary). В нем для каждого элемента определяется его позиция в исходном массиве:

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {

        var resultA = [Int]()
        var numsVoc = [Int: Int]()

        for i in 0...nums.count - 1 {

            // Основное отличие. создаем словарь вида [Int: Int] = [Число: Его позиция в массиве]
            numsVoc[nums[i]] = i
        }    

        for i in 0...nums.count - 2 {
            // Поиск в словаре разницы
            if (numsVoc[target - nums[i]] != nil && numsVoc[target - nums[i]] != i) {

                resultA.append(i)
                resultA.append(numsVoc[target - nums[i]]!)

                break
            }
        }
        return resultA
    }
}

Лучшая оценка этого результата на Leetcode:

Время — топ, потребление памяти вообще не изменилось.

Что интересного из этого решения я узнал:

Что дальше

Решаем вторую задачу из легкий — Номер палиндрома. Уже, наверное, без гугления алгоритмов :).

Есть предложения по улучшению кода? Напишите в наш чат!

← Еще задачи с собеседований

Exit mobile version