生成所有组合时的复杂性
Posted
技术标签:
【中文标题】生成所有组合时的复杂性【英文标题】:Complexity when generating all combinations 【发布时间】:2015-09-16 04:40:58 【问题描述】:我从“这可以通过为数组元素生成所有可能的组合来解决”开始的面试问题通常是为了让我找到更好的东西。
无论如何,我想补充一句“我肯定更喜欢另一种解决方案,因为这是 O(X)”。问题是:为给定集合生成所有组合的 O(X) 复杂度是多少?
我知道有 n 个! / (n-k)!k!组合(二项式系数),但如何从中获得大 O 表示法?
【问题讨论】:
您是否将k
称为常量? O(k!)
是 O(1)
吗?如果是这样,复杂度是O(n^mink,n-k)
。否则 - 不确定你是否简化了很多。
是的,给定 k 作为常数。
@amit 如果k
是一个常数,则复杂度将为O(n^k)
,因为k < n-k
对于足够大的n
而言
如果我想提及它,我会说“生成所有组合需要指数级的时间,所以......”。请注意,作为面试官,我不想留下这样的印象,即您认为指数时间解决方案在任何情况下都是可以接受的。也许从“当然我们不想为此花费指数级的时间,所以......”开始。
【参考方案1】:
首先,将O(n! / (n-k)!k!)
或任何其他函数f(n)
用作O(f(n))
并没有错,但我相信您正在寻找一种更简单的解决方案,并且仍然保持相同的集合。
如果您愿意将子集k
的大小视为常数,那么对于k <= n - k
:
n! / ((n - k)! k!) = ((n - k + 1) (n - k + 2) (n - k + 3) ... n ) / k!
但上面其实是(n ^ k + O(n ^ (k - 1))) / k!
,也就是在O(n ^ k)
中
同样,如果n - k < k
,你会得到O(n ^ (n - k))
这给了我们O(n ^ mink, n - k)
【讨论】:
n^k
的上限在n! / ( (n-k)! * k! )
之上留下了相当大的差距。恕我直言2 ^ n
是比n! / ( (n-k)! * k! )
更小的上限。看看我的answer below
你能解释一下我是如何理解这一行的吗? ``但上面实际上是 (n^k + O(n^(k-1))) / k!,也就是 O(n^k)'。你是如何得出这个结论的。【参考方案2】:
我知道这是一个老问题,但它在谷歌上是热门话题,恕我直言,接受的答案标记错误。
C(n,k) = n Choose k = n! / ( (n-k)! * k!)
上面的函数表示可以由一组 n 元素组成的 k 元素集的数量。纯粹从逻辑推理的角度来看,C(n, k)
必须小于
∑ C(n,k) ∀ k ∊ (1..n)
。
因为这个表达式代表power-set。在英文中,上述表达式表示:add C(n,k) for all k from 1 to n
。我们知道这有2 ^ n
元素。
所以,C(n, k)
的上限为2 ^ n
,对于任何n, k > 3, and k < n
,它肯定小于n ^ k
。
所以要回答你的问题,C(n, k)
的上限肯定是2 ^ n
,但不知道是否有更严格的上限可以更好地描述它。
【讨论】:
【参考方案3】:作为@amit 的后续,mink, n - k
的上限是n / 2
。
因此,“n 选择 k”复杂度的上限是 O(n ^ (n / 2))
【讨论】:
【参考方案4】:案例1:如果n-k
假设n=11,k=8,n-k=3
n!/(n-k)!k! = 11!/(3!8!)= 11x10x9/3!
let suppose it is (11x11x11)/6 = O(11^3) and 11 was equal to n so O(n^3) and also n-k=3 so it become O(n^(n-k))
案例2:如果k
假设n=11,k=3,n-k=8
n!/(n-k)!k! = 11!/(8!3!)= 11x10x9/3!
let suppose it is (11x11x11)/6 = O(11^3) and 11 was equal to n so O(n^3) and also k=3 so it become O(n^(k))
这给了我们 O(n^mink,n-k)
【讨论】:
以上是关于生成所有组合时的复杂性的主要内容,如果未能解决你的问题,请参考以下文章