这是课程中的算法练习,练习第1部分。他们说答案是O(N log N)。我不明白为什么:
int sum = 0;
for (int i = 1; i <= N; i = i*2)
for (int j = 1; j <= N; j = j*2)
for (int k = 1; k <= j; k++)
sum++;
有人可以告诉我内部循环运行的次数以及为什么答案是O(N log N)?
非常感谢您的帮助。
谢谢。
答案 0 :(得分:3)
外部循环运行log(N)次。 两个内部循环组合运行Sum_ {x = 1} ^ {log(N)} 2 ^ x次,其中每个加数表示中间循环的一次迭代。 使用几何和公式,这使得总log(N)(1-2 ^(log(N)+1))/(1-2)= log(N)(2N-1)迭代,显然是O(N * logN)
答案 1 :(得分:1)
让我们分析(将j
重写为J
)
for (int J = 1; J <= N; J = J*2)
for (int k = 1; k <= j; k++)
假设N = 2^n
。 J
的值为2^0, 2^1, 2^2, \ldots, 2^n
。
k
次循环执行J
次,因此在J = 2^j
时,它会执行2^j
次。
总的来说,我们有
2^0 + 2^1 + 2^2 + \ldots + 2^n
执行。 但这是几何级数的总和所以总和是
2^0 (2^{n+1} - 1)(2 - 1) = 2^{n+1} - 1 = O(2^n) = O(N).
这个带有i
的外圈会执行n = \log(N)
次,我们总共有O(N\log(N))
。
答案 2 :(得分:1)
最外层循环的步骤呈指数级增长:
1 2 4 8 16 32 64 128 .... N
中间循环是相同的。
两者都有log(N)
(基础2)步骤。
所以到目前为止你已经log(N) * log(N)
了。
最里面的循环运行j
次,其中j
每次都由中间循环限制/给定。它运行log(N)
次,迭代步长为1.这是一个系列:
j=1: 1
j=2: 1 2
j=4: 1 2 3 4
j=8: 1 2 3 4 5 6 7 8
j=16: 1 2 3 4 5 6 7 8 9 ... 16
...
j=N: 1 2 3 4 5 6 7 8 9 10 ... N
======================================
1 + 3 + 10 + 36 + ... + (1+2+3+4+5+...+N)
所以你有log(N) * log(N) * N
作为上限(事实上,最里面的循环比N
运行的步骤少。)
因此最后你有O(N*log^2(N))
。
我的分析不会产生O(N*log(N))
,但并不意味着它不会。也许最内层循环的边界可以改进,因为我在这里简化了N
作为所有循环的上限;我的意思是两个最里面的循环可能比O(N*log(N))
更好。如果你能看到它们是O(N)
,那么你就得到了解决方案。