我知道可以通过对数组进行排序并取更大的数字,直到满足所需条件。 这将需要至少nlog(n)的排序时间。
是否有比nlog(n)更好的方法。
我们可以假设所有数字都为正数。
我知道可以通过对数组进行排序并取更大的数字,直到满足所需条件。 这将需要至少nlog(n)的排序时间。
是否有比nlog(n)更好的方法。
我们可以假设所有数字都为正数。
O(n + size(smallest subset) * log(n))
。如果最小子集比数组小很多,则时间复杂度为O(n)
。O(n)
的时间内可用。
2. 重复从堆中提取最大元素,直到它们的总和足够大。这需要O(size(smallest subset) * log(n))
的时间。Walk through elements, until the sum of the first few exceeds S. Store current_sum.
Copy those elements into an array.
Heapify that array such that the minimum is easy to find, remember the minimum.
For each remaining element in the main array:
if min(in our heap) < element:
insert element into heap
increase current_sum by element
while S + min(in our heap) < current_sum:
current_sum -= min(in our heap)
remove min from heap
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)
log(S)
),而不会影响平均情况。我们有一个整数数组,范围有限。让每个其他轴心点位于该范围内整数的中点上,而不是数组中的值。这保证收敛于 O(log(S)) 步。(或者,您可以在最后三次选择没有足够减少搜索空间时进行确定性中位数查找。这使得复杂度为 O(n),而在平均情况下不会影响性能。) - btilly按照排序后从高到低的顺序求和元素,直到超过S。