查找n个元素的所有k个组合长度

时间:2020-05-22 08:28:13

标签: python list tree

嘿,我试图不使用任何模块而递归地找到n个元素的所有k个组合长度

例如,n = 4这样[0,1,2,3]k=3这样所有组合长度3都是

>>>[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4],[0,1,0],[0,1,1],[0,1,2]....

我试图像一棵树一样思考,但是我没有想办法从这里[0,0,4]到这里[0,1,0],我所得到的只是[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4]

2 个答案:

答案 0 :(得分:1)

我们可以通过使用简单的递归来达到最低要求。

def combination(n, k):
    if not k:
        return [[]]
    res = []
    nums = list(range(n + 1))
    for comb in combination(n, k - 1):
        for num in nums:
            comb_copy = comb.copy()
            comb_copy.append(num)
            res.append(comb_copy)
    return res

让我们看看这段代码是如何工作的。首先,与任何递归问题一样,我们建立基本情况,即k == 0。在这种情况下,我们将返回一个空的嵌套列表。

如果k != 0,则需要执行递归。这个问题的要点是我们需要在combination(n, k - 1)返回的结果上附加一些数字。例如,假设我们要获取combination(2, 2)的结果。 combination(2, 1)返回的结果将是

>>> combination(2, 1)
[[0], [1], [2]]

鉴于此信息,我们如何获得combination(2, 2)?出于直觉,这是我们想要的结果:

>>> combination(2, 2)
[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]

观察到,我们要做的就是将值012附加到combination(3, 1)的每个元素上。换句话说,采用第一个元素[0]。我们将012附加到此列表中,从而得到[0, 0], [0, 1], [0, 2]。这些是combination(3, 2)的前三个元素。

回到代码,我们首先调用combination(n, k - 1),并将num附加到该函数调用返回的嵌套列表中的每个列表中。最后,添加结束后,我们返回res

这里的一个很好的细节是我们创建列表的副本,而不是直接附加到列表。我们这样做是为了防止修改原始的comb

以下是n = 4k = 3起作用的功能:

>>> combination(4, 3)
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [0, 3, 4], [0, 4, 0], [0, 4, 1], [0, 4, 2], [0, 4, 3], [0, 4, 4], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 0], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 0], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 0, 3], [2, 0, 4], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 0], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 0], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 0], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 0, 0], [3, 0, 1], [3, 0, 2], [3, 0, 3], [3, 0, 4], [3, 1, 0], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 0], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 0], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 0], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 0, 0], [4, 0, 1], [4, 0, 2], [4, 0, 3], [4, 0, 4], [4, 1, 0], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 0], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 0], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 0], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]

请注意,我们可以通过实现诸如动态编程之类的方法来获得更好的效果,但这是您稍后可能要考虑的优化细节。

答案 1 :(得分:0)

您可以使用itertools.combinations

import itertools
itertools.combinations('ABCD', 2)