功能:
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次。我仍然在弄乱我的答案,并且不确定如何正确连接所有内容/还可以如何解决这个问题。有帮助吗?
答案 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;
}
}
这里没什么可看的,O(n)
更有趣的是,给定一个数字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)通常是用以前的术语而不是将来的术语来表示的,但我只是概述了一点,它不是严格的数学定义)