简单循环时间复杂度内的递归函数

Posted

技术标签:

【中文标题】简单循环时间复杂度内的递归函数【英文标题】:Recursive function inside a simple loop time complexity 【发布时间】:2019-08-13 17:42:23 【问题描述】:

为什么在for循环中调用递归函数会导致O(2^N)的时间复杂度而不是O(N 2^N)下面这段代码。基于CTCI一书。

void allFib(int n)
    for (int i = 0; i < n; i++) 
        System.out.println(i + ":  "+  fib(i)); 
    


int fib(n)
    if  (n  <=  0)  return 0;
    else if  (n  ==  1)  return 1; 
    return fib(n - 1)  +  fib(n -2);

【问题讨论】:

因为只取了最大的部分。同样的原因,两次遍历数组会给出O(n) 复杂性而不是O(2n) 复杂性。 2 被丢弃。 @MichaelBianconi - 然后使用您的逻辑(完全按照说明)O(n Log n) 呢? @MichaelBianconi 这是不正确的。在大 O 表示法中,您删除所有常量,但 O(2^n) 和 O(n * 2^n) 存在差异。您不能忽略非常数乘数。 @MarkRotteveel 哈哈,这不是因为 n 大,而是因为 2^0+2^1+...+2^(n-1) 小于 2^n。非常量因素无论大小都不应被忽略 @MarkRotteveel n 术语在 O(n logn) 中支配 log n。我们不会删除 log n 术语,我们也不应该将其删除 【参考方案1】:

将递归函数想象成树中的计算值。

        fib(n)
         /\
        /  \
 fib(n-1)   fib(n-2)

如果您仔细查看n = 2,则需要计算3 值,即2^(1+1) - 1 = 3,其中1 是树的高度,如in2^(h+1)-1

对于n = 3,高度为h = 2

对于n = 4,高度为h = 3

对于所有n,您需要添加所有这些: 2^2 - 1 + 2^3 - 1 + 2^4 - 1 + ....2^n - 1 -> 是2^(n+1) 的顺序

因此你得到O(2^n)

【讨论】:

以上是关于简单循环时间复杂度内的递归函数的主要内容,如果未能解决你的问题,请参考以下文章

递归算法时间复杂度分析与改善

递归函数时间复杂度分析(转)

时间复杂度和空间复杂度(转)

二分查找算法的递归循环实现及其缺陷

应该选择递归而不是迭代?

二分查找算法的递归循环实现及其缺陷