所以,我需要找到T(n),然后找到下面的代码的Big-O(紧密上限):
int sum = 0;
for(int i = 1; i < n; i *= 2) {
for(int j = n; j > 0; j /= 2) {
for(int k = j; k < n; k += 2) {
sum += i + j * k;
}
}
}
现在,根据我为循环计算的结果,第一个循环运行了log(n)次,第二个循环运行了(log(n)* log(n))次第三个循环是引起混乱的循环,因为我相信它运行了(n-j)/ 2次。我的问题是我是否可以假设它为n / 2次,因为我认为这样做不会有一个严格的上限。还是我缺少其他方法?
答案 0 :(得分:1)
这是一个非常有趣的问题。让我们给n
一个实数,然后看看它是怎么回事。说n=100
。如果我们只看两个内部循环
j k
100 None
50 50, 52, ..., 98
25 25, 27, ..., 99
12 12, 14, ..., 98
6 6, 8, ..., 98
3 3, 5, ..., 99
1 1, 3, ..., 99
如您所见,第三个循环的复杂度实际上是O(n)
。特别是当n
非常大时,它将接近Θ(n)
答案 1 :(得分:1)
for(int i = 1; i < n; i *= 2) // (1)
for(int j = n; j > 0; j /= 2) // (2)
for(int k = j; k < n; k += 2) // (3)
对于(3)的第一次迭代(其中k = j = n
),将不会发生迭代。将j
除以2后,第三个循环将运行(n / 2)/ 2或n / 4次。在(2)的第三次迭代之后,(3)将运行n / 4/2或n / 8次。我们可以将运行时间总结如下:
n/4 + n/8 + n/16 + ... + n/2^k
这也可以写成:
n * (1/4 + 1/8 + 1/16 + ... + 1/2^k)
渐近在O(n)
中。