用k-sub算法计算子集生成函数的时间复杂度

时间:2018-01-17 07:55:22

标签: algorithm time-complexity combinations

我做了一个使用k-sub算法的函数(从n个元素集合生成大小为k的所有子集)。我正在迭代它n次以创建所有大小的所有子集(即powerset)。

为什么我已经有了生成powerset的方法时使用此功能?因为我希望在子集的长度增加的情况下生成子集。

for(int k = 0; k <= n; k++){
  recursiveSelectSubset(){
    if(k == n){
       for(int i = 0; i < n; i++){
               subset[i] = true;               
       }                
    }

    if(k == 0){
       for(int i = 0; i < n; i++){
               subset[i] = false;
       }
    }

    if(k > 0 && k < n){
       subset[n-1] = true;
       recursiveSelectSubset(subset, n-1, k-1, isminimum, io);
       subset[n-1] = false;
       recursiveSelectSubset(subset, n-1, k, isminimum, io);
    }                
  }
}

现在该函数被调用了n次,所以n就在那里。但是recurciveSelectSubset函数的复杂性是什么?

我觉得这个函数产生了大小为k的所有子集,所以就像nCk一样。其复杂度为O(n ^ k)。现在它运行k的所有可能值从1到n我们可以说,这个片段的最终复杂度是O(n ^(n + 1))

这就是我计算recursiveSelectSubset的复杂性的方法。 为了生成大小为k = 0的所有子集,它将花费n ^ 0。为了生成大小为k = 1的所有子集,它将花费n ^ 1。这种方式生成大小为k = n的子集,它将花费n ^ n。总时间为n ^ 0 + n ^ 1 + .... + n ^ n = n ^(n + 1)。

但是再次怀疑,为了生成大小为k = n的子集,它应该花费不变的时间吗?不是n ^ n。所以这样我的计算出错了。但是根据nCk,可能需要n ^ n = n ^ 0 = 1.那么如何为k的所有值加总呢?

那么正确的复杂性是什么?

P.S 即可。如果我的分析错了,我想澄清它是怎么回事?

1 个答案:

答案 0 :(得分:0)

经过一些冲浪和讨论后,我找到了一个答案,我将在此处发布以供将来帮助。

recursiveSelectSubset()将计算nCk并花费时间n ^ k。正在调用此函数k = 0到n。

所以它所花费的总时间是所有recurseiveSelectSubset()调用所用时间的总和。

n ^ 0 + n ^ 1 + n ^ 2 + .... + n ^ n

这实际上是二项式系数的总和,它总计为2 ^ n。 (here

上述函数的总时间复杂度为2 ^ n。