【问题标题】:Recursion, inner loop and time complexity递归、内循环和时间复杂度
【发布时间】:2015-08-14 08:37:41
【问题描述】:

考虑以下函数:

int testFunc(int n){
    if(n < 3) return 0;
    int num = 7;
    for(int j = 1; j <= n; j *= 2) num++;
    for(int k = n; k > 1; k--) num++;
    return testFunc(n/3) + num;
}

我知道第一个循环是 O(logn),而第二个循环是 O(n),总时间复杂度是 O(n)。但是由于递归调用,我认为时间复杂度会是 O(nlogn),但显然它只是 O(n)。谁能解释一下为什么?

【问题讨论】:

    标签: algorithm recursion time-complexity


    【解决方案1】:

    递归调用几乎给出了以下复杂度(表示输入 n 的复杂度,T(n)):

    T(n) = log(n) + n + T(n/3)
    

    您正确指出的第一个观察结果是您可以忽略对数,因为它以n 为主。现在我们只剩下T(n) = n + T(n/3)。例如,尝试将其写入 0。我们有:

    T(n) = n + n/3 + n/9+....
    

    你可以很容易地证明上面的和总是小于2*n。事实上,可以证明更好的限制,但这足以说明整体复杂度为O(n)

    【讨论】:

    • 比 IMO 的主定理更容易理解。另外,总和也小于1.5*n
    • 啊,我明白了。这是一个几何级数。很好解释
    • @novalain 是的,而 JohnBupit 提到的值 1.5 正是由于几何回归的总和而可能是最严格的界限
    【解决方案2】:

    对于使用递归算法的过程,例如:

    procedure T( n : size of problem ) defined as:
         if n < base_case then exit
    
         Do work of amount f(n) // In this case, the O(n) for loop
    
         T(n/b)
         T(n/b)
         ... a times... // In this case, b = 3, and a = 1
         T(n/b)
    end procedure
    

    应用Master theorem 来查找时间复杂度,在这种情况下,f(n)O(n)(由于第二个 for 循环,就像你说的那样)。这使得c = 1.

    现在,logba = log31 = 0,这就是定理的第三种情况,根据这个时间复杂性T(n) = Θ(f(n)) = Θ(n).

    【讨论】:

    • 由大师定理,T(n) = a*T(n/b)+f(n)。将 a、b 和 f(n) 的值替换为 1,3,我们知道 f(n) = n+log(n) => f(n) =n(就像 @john-bupit 的回答一样)。我们得到T(n) = 1*T(n/3)+n => T(n) = T(n/3)+n。现在看看@Ivaylo-strandjev 的答案。就像他说的那样,这将等于T(n) = n + n/3 + n/9+ ... => O(n)。希望这可以帮助。谢谢你们。即使我无法回答但通过比较答案它帮助了我,我应该感谢你们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多