该代码的时间复杂度是多少?我的老师和我不同意

时间:2019-05-24 09:59:03

标签: time-complexity big-o

我得到了这段代码(函数)。

enter image description here

如果我以n = 10来运行它,根据runCounter,它总共被调用了2047次。如果我在n = 20的情况下运行它,那么在完成之前总共被称为2,097,151次。

据我的老师说,这段代码的时间复杂度为O(n ^ 2),但我不知道为什么。 10 ^ 2 = 100。在2047和20 ^ 2 = 400附近,甚至还有更多错误。我认为这段代码更符合O(2 ^ n),因为2 ^ 10 = 1024和2 ^ 20 = 1,048,576更符合函数的行为。我是对的还是老师是对的?

有没有简单的方法来解决这些问题?我尝试将Call堆栈写在纸上,并了解正在发生的事情,但是那是图形的,我怎么用纯粹的数学术语来编写它?

1 个答案:

答案 0 :(得分:1)

实际上,复杂度似乎是O(2^(n+1))。在递归函数中进行的方法调用将采用平衡二叉树的形式,其高度为n + 1,输入n

面对这样的问题,一种好的计算机科学方法是只写出方法调用的数量。对于n = 5的输入,下面是方法调用的数量:

n=5 -> n=4, n=4 (2 calls)

n=4 -> n=3, n=3 (4 calls)
n=4 -> n=3, n=3

n=3 -> n=2, n=2 (8 calls)
n=3 -> n=2, n=2
n=3 -> n=2, n=2
n=3 -> n=2, n=2

n=2 -> n=1, n=1 (16 calls)
n=2 -> n=1, n=1
n=2 -> n=1, n=1
n=2 -> n=1, n=1
n=2 -> n=1, n=1
n=2 -> n=1, n=1
n=2 -> n=1, n=1
n=2 -> n=1, n=1

n=1 -> (32 calls to n=0, then the recursion ends)

因此,用生成的n=5进行呼叫:

1 + 2 + 4 + 8 + 16 + 32 = 63 calls

这等效于:

2^(5+1) - 1 = 2^(n+1) - 1

因此,复杂度实际上是O(2^(n+1)),而不是O(n^2)Here is a link进入Wikipedia页面,该页面还显示了平衡二叉树中节点数的相同公式。