递归函数的时间复杂度

时间:2021-06-04 09:32:09

标签: algorithm time time-complexity

我是一名计算机科学专业的学生,​​下周我参加了期末考试,我在试图找出以下函数的时间复杂度时感到困惑。你能向我解释一下吗?

int bss(int n){
    if(n <= 1)
        return n;
    
    return bss(n/2) + bss(n/2);
}

1 个答案:

答案 0 :(得分:2)

对于这样的问题,你应该先弄清楚递推关系(通过查看代码),然后解决递推关系(使用数学)。

要进行第 1 步,我们需要查看每一行,看看它对我们算法的整体运行时间 T(n) 有何贡献:

int bss(int n){
    if(n <= 1)                        // contributes a constant time a
        return n;                     // contributes a constant time b in the base case only

    return bss(n/2) + bss(n/2);       // contributes a constant time c
                                      // for the two divisions and one addition,
                                      // plus 2T(n/2)
}

加起来,我们得到两种情况:

n <= 1: T(n) = a + b
n  > 1: T(n) = a + c + 2T(n/2)

为了解决这个系统,我们可以开始写出 n 值的项。因为我们将 n 除以 2,所以我们甚至可以只选择 n。另外,最好已经计算了 T(n/2) 来计算 T(n);因此,我们每次都可以将 n 的测试值加倍。

n    T(n)
---------
1    a + b
2    a + c + 2T(1) = a + c + 2a + 2b = 3a + 2b + c
4    a + c + 2T(2) = a + c + 6a + 4b + 2c = 7a + 4b + 3c
8    a + c + 2T(4) = a + c + 14a + 8b + 6c = 15a + 8b + 7c
16   a + c + 2T(8) = a + c + 30a + 16b + 14c = 31a + 16b + 15c
...
k    (2k - 1)a + kb + (k - 1)c

根据我们看到的模式,似乎 n = k 的解决方案是 (2k - 1)a + kb + (k - 1)c。我们可以尝试通过将其代入我们的方程来验证这一点:

k = 1: (2k - 1)a + kb + (k - 1)c = a + b = T(1) ... correct
k > 1:

(2k - 1)a + kb + (k - 1)c ?= a + c + 2[(2k/2 - 1)a + (k/2)b + (k/2 - 1)c]
                          ?= a + c + (2k - 2)a + kb + (k - 2)c
                          ?= a + c + 2ka - 2a + kb + kc - 2c
                          ?= -a -c + 2ka + kb + kc
                          ?= (2k - 1)a + kb + (k - 1)c ... correct

因此,我们找到了递归关系的有效解。解决办法是:

T(n) = (2n - 1)a + nb + (n - 1)c

重新排列:

T(n) = (2a + c + 1)n - (a + c)

T(n) 是一条直线的方程。