如何从输入的数字

时间:2017-10-09 15:23:33

标签: python combinations

我程序的输入是按升序排序的数字列表。

我需要的输出是K-最大的由列表中的3个数字组合组成的总和。

由于这可能有点混乱,让我解释一下我的算法:

  • 我的列表包含数字1 2 3 4,我需要K最大的总和
  • 将所有可能的组合列为列表([1,2,3],[1,2,4],[1,3,4],[2,3,4])
  • 列出包含每个组合之和的列表([6],[7],[8],[9])
  • 按降序排序列表,并在第K个位置打印数字

这是我在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])

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的有用评论,这个算法在评论中描述了一些问题,并没有给出总是正确的结果。我今天稍后会尝试修改或删除它......