如何找到该函数的T(n)?

时间:2018-08-28 20:57:30

标签: algorithm performance

功能:

for (int i = 0; i < n; i++) {
    for (int j = i; j > 0; j /= 2){
        std::cout << j << endl;
    }
}

我刚被介绍过这些东西,这个问题使我不寒而栗。由于内部for循环连接到i,因此它将运行log(n!)次。也就是说,由于log(a)+ log(b)= log(a * b)。并且外循环运行n次。我仍然在弄乱我的答案,并且不确定如何正确连接所有内容/还可以如何解决这个问题。有帮助吗?

2 个答案:

答案 0 :(得分:0)

要计算内部循环运行的时间从此开始: 当j = 0且j start = i且每次半等距时,循环停止,因此在迭代k中,您有i / 2 ^ k,当i / 2 ^ k = 1时,它到达了最后一个迭代,因此取log2和结果为k = log2(i)+1,再加上一个,因为它需要进行另一次迭代。因此,内部循环执行k = log2(i)+1迭代。现在,您可以将两个循环运行的时间表示为: i = 1到i = N的总和j = 1到j = \ log2(i)+1 \的总和。

但是,如果您对T(n)感兴趣,只需将外循环的次数乘以内循环的最大时间即可,因此内循环的最大值为log2(n),因此您得到: T(n)= O(n log2(n))

其中\ log2(i)+1 \是较低的整数

答案 1 :(得分:0)

当然,您的方法看起来不错。

还有另一种看问题的方法。

for (int i = 0; i < n; i++) { // loop 1
    for (int j = i; j > 0; j /= 2){ // loop 2
        std::cout << j << endl;
    }
}

循环1的分析

这里没什么可看的,O(n)

第2循环分析

更有趣的是,给定一个数字j(= i),这是一场竞赛,看看在获得0之前可以除以2多少次。

将每个n的两个分析结合起来,就可以执行log(n,2)-> log(number,base)。

O(n * log(n,2))

通过名为Stirling's Approximation的事物,您可以证明O(nlogn)O(log(n!))

现在需要指出的是,您要求的 T(n) O(n) 稍有不同。

T(n) 是用于数学表示算法的相对于其下一个处理步骤和当前步骤的东西。

对于诸如合并排序之类的

T(n) = 2 * T(n/2)(divide) + O(n)(conquer)

在我们的情况下,我将 T(n) 写为

T(n) = T(n + 1)(next step) + O(logn)(race to zero)   , 0 <= n < N
     = 0                                             , n >= N

(我知道T(n)通常是用以前的术语而不是将来的术语来表示的,但我只是概述了一点,它不是严格的数学定义)