我想弄清楚这个简单程序的时间复杂程度是什么,但我似乎无法理解这是最好的方法。
我已经为每一行并列了时间复杂度
1 public int fnA (int n) {
2 int sum = 0; O(1)
3 for (int i = 0; i < n; i++) { O(n)
4 int j = i; O(n)
5 int product = 1; O(1)
6
7 while (j > 1) { O(n)
8 product ∗= j; O(log n)
9 j = j / 2; O(log n)
10 }
11 sum += product; O(1)
12 }
13 return sum; O(1)
14 }
我是否正确假设这些运行时间并且最终运行时间为:O(n)
如果没有,有人能够解释我的错误吗?
总体而言:
1 + n + n + 1 + n + logn + logn + 1 + 1
= 3n + 2logn + 4
Final: O(n)
答案 0 :(得分:2)
该算法的时间复杂度为O(NlogN)
。
for
循环执行N
次(从0
到N
)。
while
循环执行logN
次,因为您每次将数字除以一半。
由于您正在执行while
内的for
,您正在执行logN
次N
次操作,从那里O(NlogN)
。< / p>
您可以假设所有剩余的操作(赋值,乘法,除法,求和)O(1)
答案 1 :(得分:2)
上述程序的关键是while循环,它是定义因素,其余行的复杂性不会超过O(n),并假设算术运算将在O(1)时间内运行。
mainMixerNode
以上循环的运行时间为O(log(j)),j从1变为n,所以它的系列......
while (j > 1) {
product ∗= j;
j = j / 2;
}
有关上述证明,请参阅this
答案 2 :(得分:1)
对于每个我都没有,logn
循环正在运行,因此对于n
元素,总复杂度为nlogn
。
因为您知道以下循环需要登录。
while (j > 1) {
product ∗= j;
j = j / 2;
}
现在为每个i
执行此特定循环。所以这将被执行n
次。所以它变成了nlogn
。
答案 3 :(得分:0)
首先,您可以统计所有操作。例如:
1 public int fnA (int n) {
2 int sum = 0; 1
3 for (int i = 0; i < n; i++) {
4 int j = i; n
5 int product = 1; n
6
7 while (j > 1) {
8 product ∗= j; ?
9 j = j / 2; ?
10 }
11 sum += product; n
12 }
13 return sum; 1
14 }
现在我们可以进行计数:总计:2 + 3n + nlog(n)
在许多程序中,计数更复杂,通常有一个突出的高阶项,例如:2 + 3n + 2n 2 。在谈论性能时,我们非常关心当n很大时,因为当n很小时,总和很小。当n很大时,更高阶项将绘制其余部分,因此在本例中 2n 2 实际上是重要的术语。所以这就是波浪线近似的概念。
考虑到这一点,通常可以快速识别最常执行的代码部分,并使用其计数来表示总体时间复杂度。在OP给出的示例中,它看起来像这样:
for (int i = 0; i < n; i++) {
for (int j = i; j > 1; j /= 2)
product *= j;
}
给出Σlog 2 n。通常计数涉及离散数学,我学到的一个技巧就是用它替换积分并做caculus:∫log 2 n = nlog(n)