我程序的输入是按升序排序的数字列表。
我需要的输出是K-最大的由列表中的3个数字组合组成的总和。
由于这可能有点混乱,让我解释一下我的算法:
这是我在python中的程序,但问题是它花了很多时间做多组合。有时我的列表包含3000个数字,创建所有可能的组合需要很长时间。
有什么方法可以避免做所有这些组合吗?
import itertools
k = input('Here goes the K').split()
array = [int(x) for x in input('Here goes list of numbers').split()]
k=int(k)
combs=[]
result=[]
result=[sum(x) for x in itertools.combinations(array,3)]
result.sort(reverse=True)
print(result[k-1])
答案 0 :(得分:1)
以下是我的第二次编辑尝试,其中包含时间复杂度O(nlogn + K)
和空间复杂度O(n)
。
L = [9, 8, 7, 6, 2, 1]
K = 3
L = sorted(L,reverse = True)
N = len(L)
i, j, l = 0, 1, 2
A = [c-v for c, v in zip(L[:-1], L[1:])]+[0]
while(K-1>0):
if(l < N-1 and (A[l] < A[j] or j==l-1) and (A[l] < A[i] or i==j-1) ):
l+=1
elif(j < N-2 and (A[l] < A[i] or i==j-1) ):
j+=1
else:
i+=1
K-=1
print '{}\n{}\n{}'.format(L[i],L[j],L[l])
Haven没有对角落案件进行太多测试,但我认为这很好。
的示例
L = [9, 8, 7, 6, 2, 1]
输出:
9
7
6
解释 - 算法正确性
上述算法以三个指针i,j,l开始,指向排序列表的第一,第二和第三个元素,这是最大总和的组合。
然后计算每个i的L[i+1],L[i]
之间的差异,然后循环K-1
次以找到第k个最大sim组合。在每次迭代中,为了保证我们移动右指针以实现下一个更大的和,我们移动可以移动的指针(例如,在数组索引内,并且不与下一个指针重叠),并且{{{ 1}}。在L[i]
次迭代后,我们找到第k个最大和组合。
示例输入的步骤是:
K-1
-
修改强>
感谢@Jared Goguen的有用评论,这个算法在评论中描述了一些问题,并没有给出总是正确的结果。我今天稍后会尝试修改或删除它......