Если k очень близко к 1 или N, любой алгоритм, который генерирует отсортированные суммы лениво, может просто выполняться, пока не появится k-й или N-й элемент.
В частности, я имею в виду поиск наилучшего первого в следующем пространстве: (a, b) означает элемент ath из A, первый список, добавленный к bth из B, второй.
Хранить в лучшем = пары очередей с самым низким приоритетом (a, b) со стоимостью (a, b) = A [a] + B [b].
Начните с просто (1,1) в очереди приоритетов, что является минимумом.
Repeat until k items popped:
pop the top (a,b)
if a<|A|, push (a+1,b)
if a=1 and b<|B|, push (a,b+1)
Это дает вам соединение с зубчатым гребнем и избавляет вас от необходимости отмечать каждый (a, b) посещенный в массиве. Обратите внимание, что стоимость (a + 1, b)> = стоимость (a, b) и стоимость (a, b + 1)> = стоимость (a, b), потому что A и B отсортированы.
Вот изображение гребня, на котором показано правило генерации преемника выше (вы начинаете в верхнем левом углу; a - горизонтальное направление):
|-------
|-------
|-------
Это просто лучшее первое исследование (до) всех | A | * | B | кортежи и их суммы.
Обратите внимание, что наиболее вероятные элементы, помещаемые перед выталкиванием k, равны 2 * k, поскольку каждый элемент имеет 1 или 2 преемника. Вот возможное состояние очереди, когда элементы, помещенные в очередь, помечены *
:
|--*----
|-*-----
*-------
Все выше и слева от границы *
уже вытолкнуто.
Для случая N-k<k
сделайте то же самое, но с обратным порядком очередности приоритетов и порядком исследования (или, просто отрицайте и меняйте значения, получите наименьшее (Nk) число, затем отрицайте и возвращайте ответ).
См. Также: отсортированный список парных сумм на SO или Проект открытых задач .