Сумма двух чисел в отсортированном массиве

Средняя

Описание задачи #

Дан массив целых чисел nums, отсортированный в возрастающем порядке. Напишите функцию twoSum для поиска в массиве двух чисел, сумма которых равна целевому числу target. В качестве результата функция должна возвращать массив с индексами элементов удовлетворяющих условию. Отсчет индексов начинается с единицы.


Ограничения #


Примеры #

  • Входные данные

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

    Ответ: [1, 3]

    Сумма 2 и 7 равна 9. Следовательно, index1 = 1, index2 = 3.
    Возвращаем [1, 3].

  • Входные данные

    nums = [-1, 0]
    target = -1
    

    Ответ: [1, 2]]

    Сумма -1 и 0 равна -1. Следовательно, index1 = 1, index2 = 2.
    Возвращаем [1, 2].

Решение #

Решение этой задачи сильно упрощается дополнительными условиями:

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

  1. Заводим два указателя, которые будут хранить индексы. Значение left делаем равным 0, значение right равным индексу последнего элемента.
  2. Запускаем цикл, который прервется, если left станет больше или равен right, то есть когда индексы сойдутся.
  3. На каждой итерации высчитываем сумму элементов под индексами left и right и проверяем ее на равенство с target.

Таким образом мы перебираем все возможные комбинации и находим конечный ответ.

  • package main
    
    func twoSum(nums []int, target int) []int {
    	// Устанавливаем левый указатель в нулевой индекс
    	left := 0
    
    	// Устанавливаем правый указатель в индекс последнего элемента в слайсе
    	right := len(nums) - 1
    
    	// Запускаем цикл, который прервется, если `left` и `right` сойдутся
    	for left < right {
    		sum := nums[left] + nums[right]
    
    		if sum == target {
    			return []int{left + 1, right + 1}
    		} else if sum > target {
    			right--
    		} else {
    			left++
    		}
    	}
    
    	// Если ничего не нашли возвращаем [-1, -1]
    	return []int{-1, -1}
    }

  • export const twoSum = (nums: number[], target: number): number[] => {
        // Устанавливаем левый указатель в нулевой индекс
        let left = 0
    
        // Устанавливаем правый указатель в индекс последнего элемента в массиве
        let right = nums.length - 1
    
        // Запускаем цикл, который прервется, если `left` и `right` сойдутся
        while (left < right) {
            const sum = nums[left] + nums[right]
    
            if (sum === target) {
                return [left + 1, right + 1]
            } else if (sum > target) {
                right--
            } else {
                left++
            }
        }
    
        // Если ничего не нашли возвращаем [-1, -1]
        return [-1, -1]
    }

Оценка сложности #

n - количество элементов в массиве.

По времени

Сложность по времени O(n), так как мы итерируемся по всем элементам массива.

По памяти

Сложность по памяти O(1), так как мы используем только три переменных для хранения индексов и суммы.

Оригинал задачи на Leetcode
< Предыдущая задача
Следующая задача >