特定函数big-O的时间复杂度

时间:2017-02-12 22:30:12

标签: time-complexity big-o

如果之前已经回答,我会事先道歉。

我了解以下代码的时间复杂度为 O(n!)

void permutations(int n){
  if(n!=0){
    for(int i=0; i<n; i++){
      permutations(n-1);
    }//for
  }//if
}//permutations

另外我理解以下代码的时间复杂度为 O(2 ^ n)

void permutations(int n){
  if(n!=0){
    permutations(n-1);
    permutations(n-1);
  }//if
}//permutations

但是我无法确定以下代码的复杂程度,我怀疑它是 O((n ^ 2)*(n!)),但我不确定是否是正确的。如果有人能解释我是对的,为什么会这样,我将不胜感激。

void permutations(int n){
  if(n!=0){
    for(int i=0; i<n; i++){
      permutations(n-1);
      permutations(n-1);
    }//for
  }//if
}//permutations

1 个答案:

答案 0 :(得分:0)

我相信你有一个拼写错误并且意味着 O((2 ^ n)*(n!)),这就是答案。

Layman的方法:

没有做证明(我自己有点生锈),考虑n = 4:

  • 在n = 4时,我们循环4次,每次迭代两次调用permutations(3)。总共有4 x 2 = 8个电话。

  • 在n = 3时,我们循环3次,每次迭代调用permutations(2)两次,但是在n = 4时,我们进行了8次这样的调用。所以总共3 x 2 x 8 = 48个电话。

  • 在n = 2时,我们循环2次,每次迭代调用permutations(1)两次,但是在n = 3时,我们进行了48次这样的调用。总共2 x 2 x 48 = 192次来电。

  • 在n = 1时,我们循环1次,每次迭代调用permutations(0)两次,但是在n = 2时,我们进行了192次这样的调用。所以总共1 x 2 x 192 = 384个电话。

  • 我们不关心n = 0,因为这是基本情况。

检查递归的增长情况,我们只需调用permutations(4)即可增加到384次调用。从这个数字向后工作:

  • 384 == 1 x 2 x 192

  • 1 x 2(2 x 2 x 48)

  • ...

  • 1 x 2 x(2 x 2 x(3 x 2 x(4 x 2)))

  • 2 x 2 x 2 x 2 x 4 x 3 x 2 x 1

  • 2 ^ 4 x 4!

看起来我们可以推断它是 O((2 ^ n)*(n!))

解决复发关系:

现在我已经使用杜克大学的Big-Oh for Recursive Functions: Recurrence Relations修改了解决递归关系的问题,并采用了解决这个问题的方法:

  • 让T(n)执行permutations(n),T(0)= 1。
  • 我们知道T(n)= n x 2 x T(n-1)
    • 这是因为循环n次,执行两次排列(n-1)。
  • T(n)= n x 2 x((n-1)x 2 x T(n-2))
  • T(n)= n x 2 x((n-1)x 2 x((n-2)x 2 x T(n-3)))
  • 因此我们可以将此推广为k展开,如T(n)= 2 ^ k * k!
    • 我们可以观察到因子n,n-1,n-2,...,1(在基本情况下),这是因子分量(k!)。
    • 在每次扩展时,我们有额外的因子2,因此2 ^ k。
  • 基本情况是n = 0,我们有k = n

因此 O((2 ^ n)*(n!))