长度为 N 的可重复组合有多少个?

Posted

技术标签:

【中文标题】长度为 N 的可重复组合有多少个?【英文标题】:How many sum of repeatable combinations of length N? 【发布时间】:2020-12-28 12:38:00 【问题描述】:

如 [1,3,5,10],N = 4。

还有

[1,1,1,1] -> sum is 4

[1,1,1,3] -> sum is 6

...

[10,10,10,10] -> sum is 40

我执行回溯算法。通过python3

res = set()
n = 4
def backtrack(k, path):
    if len(path) == n:
        res.add(sum(path))
        return
    backtrack(k+1, path+[1])
    backtrack(k+1, path+[3])
    backtrack(k+1, path+[5])
    backtrack(k+1, path+[10])
    return
backtrack(0, list())

有没有更有效的解决方案?

【问题讨论】:

那是 Python,不是吗?考虑标记它以吸引更多潜在有用的用户。 【参考方案1】:

如果n elements 命令不重要,那么你的代码是错误的 例如 [1,1,2,2] ~ [1,2,1,2]

您可以创建一个新列表并重复原始n 的每个元素次。那么问题是how many ways we can select n item from new list 可以很容易地计算出来 如果您想要所有sums 的结果集,我认为没有比在所有情况下迭代更好的方法了。

【讨论】:

感谢您的回答。但是res有一个set(),我想计算N长度的组合之和(顺序不重要) 就像玩N轮游戏一样,每轮可以随机得到1、3、5、10点,你最终会得到多少个结果? 我的问题是,除了回溯还有其他方法吗? 因为在这种情况下,时间复杂度将是指数级的。【参考方案2】:

O(n*len(list)*numberofdistinctsums) 接近。

我们有两组包含奇数步和偶数步的当前可能总和。 我们从上一步的总和(使用i summands)计算由i+1 summands 形成的新总和。

例如,在两轮之后,我们得到了两个被加数的所有可能和。从之前的集合中得到 sum 8,我们将三个 summands 8+1, 8+3,8+5, 8+10 的和放入新的集合中,依此类推。

a = [1,3,5,10]
n = 4
sums = [set(a), set()]
for i in range(1, n):
    sums[i%2].clear
    for j in sums[(i+1)%2]:
        for x in a:
            sums[i%2].add(j + x)

print(len(sums[(n-1)%2]))

【讨论】:

mod 2有什么用? @Obito Kang 在两组之间触发 - 一组用于偶数步,另一组用于奇数步 所以我们从前一步的总和(带有 i 总和)中得到新的总和(带有 i+1 总和) 因为长度会是N,所以和的下界应该是[1,1,1,...,1] == N,上界会是[10,10 ,10,...,10] == 10*N 问题中没有 10 个限制。由于限制如此之小,我们也可以使用数组(列表)而不是集合,但运行时间仍然很接近。 (我在答案中更正了设置方法的时间估计)

以上是关于长度为 N 的可重复组合有多少个?的主要内容,如果未能解决你的问题,请参考以下文章

数组(组合数学)

【基础】Python3小程序_之排列组合

含有重复字符的字符串排列组合

长度为n的顺序表顺序查找时,当查找成功时候的平均查找长度为多少,不成功时又是多少?

从给定的单词列表中生成具有“N”长度的所有可能组合(寻找不重复)

面试题3:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为