![](/img/trans.png)
[英]Finding the minimum from last K elements , after each insertion , where K is not fixed in less than O(n) time
[英]Finding k elements of length-n list that sum to less than t in O(nlogk) time
這是《 Programming Pearls》編輯的。 2,第2欄,問題8:
給定一組n個實數,一個實數t和一個整數k,您可以多快確定是否存在該集合的k個元素子集,總和最多為t?
一個簡單的解決方案是對前k個元素進行排序和求和,這是我們找到此類和的最大希望。 但是,在解決方案部分中,Bentley提到需要花費nlog(k)時間的解決方案,盡管他沒有提供有關如何找到它的提示。 我一直在為此苦苦掙扎; 我曾經想過要遍歷列表,並添加所有少於t / k的元素(以O(n)時間計); 假設有m1 <k個這樣的元素,它們的和等於s1 <t。 然后我們剩下k-m1個元素,因此我們可以在O(n)時間內再次掃描列表,以查找所有小於(t-s1)/(k-m1)的元素。 再次相加,得到s2和m2,如果m2 <k,則再次查找小於(t-s2)/(k-m2)的所有元素。 所以:
def kSubsetSumUnderT(inList, k, t):
outList = []
s = 0
m = 0
while len(outList) < k:
toJoin = [i for i in inList where i < (t - s)/(k - m)]
if len(toJoin):
if len(toJoin) >= k - m:
toJoin.sort()
if(s + sum(toJoin[0:(k - m - 1)]) < t:
return True
return False
outList = outList + toJoin
s += sum(toJoin)
m += len(toJoin)
else:
return False
我的直覺是,這可能是O(nlog(k))算法,但是我很難向自己證明。 思考?
考慮以下示例,其中t> 0和all([x>t for x in inList])
toJoin
將始終為空,並且您的算法甚至無法完成,更不用說O(nlog(k))了。
運行時間Theta(n log k)的自然算法可能是初始化具有k個無窮大的max-heap,然后遍歷數組,推送新元素並彈出max,最后將k留在堆中最少。 (正如Bentley提到的那樣,在Theta(n)時選擇速度漸近。在實踐中,最好的選擇方法是將最小的k次堆放並彈出,這是Theta(n + k log n)= Theta(n)當k = O(n / log n)時。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.