我得到了这段代码(函数)。
如果我以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堆栈写在纸上,并了解正在发生的事情,但是那是图形的,我怎么用纯粹的数学术语来编写它?
答案 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页面,该页面还显示了平衡二叉树中节点数的相同公式。