Вот решение задачи с ожидаемым временем O(n). Это чем-то похоже на идею Морона, но мы не выбрасываем работу, которую проделывал наш алгоритм выбора на каждом шаге, и начинаем пробовать с элемента, потенциально находящегося посередине, вместо того, чтобы использовать метод повторного удвоения.
В качестве альтернативы, это просто быстрый выбор с небольшим дополнительный учет на оставшуюся сумму.
Во-первых, ясно, что если бы у вас были элементы в отсортированном порядке, вы могли бы просто выбирать сначала самые большие элементы, пока не превысите желаемую сумму. Наше решение будет таким, за исключением того, что мы будем изо всех сил стараться не обнаруживать информацию о заказе, потому что сортировка медленная.
Вы хотите иметь возможность определить, является ли данное значение отсечением. Если мы включим это значение и все, что больше его, мы достигнем или превысим S, но когда мы удалим его, мы окажемся ниже S, тогда мы будем золотыми.
Вот псевдокод, я не проверял его на пограничные случаи, но идея понятна.
def Solve(arr, s):
# We could get rid of worse case O(n^2) behavior that basically never happens
# by selecting the median here deterministically, but in practice, the constant
# factor on the algorithm will be much worse.
p = random_element(arr)
left_arr, right_arr = partition(arr, p)
# assume p is in neither left_arr nor right_arr
right_sum = sum(right_arr)
if right_sum + p >= s:
if right_sum < s:
# solved it, p forms the cut off
return len(right_arr) + 1
# took too much, at least we eliminated left_arr and p
return Solve(right_arr, s)
else:
# didn't take enough yet, include all elements from and eliminate right_arr and p
return len(right_arr) + 1 + Solve(left_arr, s - right_sum - p)
person
Rob Neuhaus
schedule
12.05.2011
n lg(n)
на сортировку сравнением, заключается в том, что вы не знаете заранее, в каком диапазоне находятся значения, сколько их и т. д. Зная часть этой информации заранее, вы сможете выполнять несравнительную сортировку. работать лучше в некоторых случаях. - person verdesmarald   schedule 11.05.2011