Мы используем максимальную кучу, как воригинальная формулировка;мы помещаем тройки в кучу, используя их суммы (S [...]) в качестве ключа заказа.Алгоритм начинается с нажатия [0,0,0] в кучу.Тогда:
answer = []
for m in 0 .. k:
top = heap.pop()
answer.append(sum(top))
(i,j,n) = top # explode the tuple
if (n < k - 1):
heap.push((i,j,n+1))
if (j == n):
heap.push((i,j+1,j+1))
if (i == j):
heap.push((i+1,i+1,i+1))
В конце ответ содержит k + 1 элементов, первый из которых - [0,0,0], которые необходимо отбросить.
Пусть задано как-1, -3, -8, -9.Затем алгоритм работает следующим образом:
Heap
Top Rest (shown in order)
[ 0, 0, 0] |
[ 0, 0,-1] | [ 0,-1,-1] [-1,-1,-1]
[ 0,-1,-1] | [-1,-1,-1] [ 0,-1,-3] [ 0,-3,-3]
[-1,-1,-1] | [-1,-1,-2] [ 0,-1,-3] [-1,-2,-2] [-2,-2,-2] [ 0,-3,-3]
[-1,-1,-2] | [ 0,-1,-3] [-1,-1,-3] [-1,-2,-2] [-2,-2,-2] [ 0,-3,-3]
[ 0,-1,-3] | [-1,-1,-3] [ 0,-1,-4] [-1,-2,-2] [-2,-2,-2] [ 0,-3,-3]
[-1,-1,-3] | [ 0,-1,-4] [-1,-1,-4] [-1,-2,-2] [-2,-2,-2] [ 0,-3,-3]
[ 0,-1,-4] | [-1,-2,-2] [-1,-1,-4] [ 0,-1,-5] [-2,-2,-2] [ 0,-3,-3]
...
etc.
Приятной особенностью этого алгоритма является то, что он не перечисляет дубликаты и размер кучи равен O (k);чтобы понять почему, обратите внимание, что алгоритм добавляет на каждой итерации максимум элементов в куче (часто меньше), поэтому после k итераций в куче не может быть более 2k элементов.
Это дает тогда время выполненияO (n log k + k log k) = O ((n + k) log k).