算法运行时间
Algorithm runtime
你能帮我计算一下这个函数的运行时间吗?
我猜是 O(n log n)
n 用于 for 循环,log n 用于 while 循环。
但让我不确定的是 j = j*3。
如果它是 j = j/2,那么我就会确定我的答案。
即使是 j = j*3 或 j = j/3,它是否是 log n?
如果是 j = j*3
,那么对于 j = j*2
,复杂度将只是 O(n*log_3(n))
而不是 O(n*log_2(n))
,因为它们仅相差一个常数因子,该因子将被吸收Big-O
表示法。
来到你的函数,外循环肯定是 O(n)
但内循环并不完全 log_3(n)
每次。它实际上随着每次迭代而减少。扩展将是:
log_3(n) + log_3(n-1) + log_3(n-2) + ... + log_3(1)
由于上面解释的原因忽略碱基,我们可以写成:
log(n) + log(n-1) + log(n-2) + ... + log(1)
一种评估方法是通过 log(n)
对上述每一项进行上限,即
log(n) + log(n-1) + log(n-2) + ... + log(1) <= log(n) + log(n) + log(n) + ... + log(n)
<= n*log(n)
因此,复杂度可以写成O(n*log(n))
.
第二种方法如下。重写上面的等式,我们有:
log(n) + log(n-1) + log(n-2) + ... + log(1)
= log(n*(n-1)*(n-2)...1)
= log(n!)
因此,复杂度当然可以写成O(log(n!))
。但是 log(n!)
呢?根据Stirling's approximation、
log(n!) ~ n*log(n) - n + O(log(n))
请注意,根据维基百科:
It is a very powerful approximation, leading to accurate results even for small values of n.
因此,我可以假设对于 n
的大值(我们真正关心的情况),这将非常准确。显然,在上面的近似中,n*log(n)
的值支配其他项,因此,在 Big-O
表示法中,我可以写:
O(log(n!)) = O(n*log(n))
嵌套循环的时间复杂度等于innermost语句执行的次数。例如:
for ( int i = 1; i <= n; i ++ ) {
for ( int j = 1; j <= n; j ++ ) {
// O(1) expressions
}
}
在这种情况下 (log_3(n)),您可以使用像这样的小 C++ 代码对其进行测试:
int main()
{
const int N = 10;
int j;
int count = 0;
int totalCount = 0;
for ( int i = 1; i <= N; i++ ) {
j = i;
while ( j <= N ) {
j = j * 3;
count++;
}
std::cout << " " << i <<"th iteration of outer loop : inner loop will iterate " << count << " times" << std::endl;
totalCount += count;
count = 0;
}
std::cout << "TOTAL COUNT is : " << totalCount << std::endl;
return 0;
}
你在哪里得到这样的结果:
1th iteration of outer loop : inner loop will iterate 3 times
2th iteration of outer loop : inner loop will iterate 2 times
3th iteration of outer loop : inner loop will iterate 2 times
4th iteration of outer loop : inner loop will iterate 1 times
5th iteration of outer loop : inner loop will iterate 1 times
6th iteration of outer loop : inner loop will iterate 1 times
7th iteration of outer loop : inner loop will iterate 1 times
8th iteration of outer loop : inner loop will iterate 1 times
9th iteration of outer loop : inner loop will iterate 1 times
10th iteration of outer loop : inner loop will iterate 1 times
TOTAL COUNT is : 14
更严格的上限是 O(n)。
因为总时间是 ( Sum(i=1 to n) of (log(n/i)) ) = log(n^n/n!) = O(n)
如果重要的话,运行 时间实际上是 Θ(n)。
你能帮我计算一下这个函数的运行时间吗?
我猜是 O(n log n) n 用于 for 循环,log n 用于 while 循环。
但让我不确定的是 j = j*3。 如果它是 j = j/2,那么我就会确定我的答案。
即使是 j = j*3 或 j = j/3,它是否是 log n?
如果是 j = j*3
,那么对于 j = j*2
,复杂度将只是 O(n*log_3(n))
而不是 O(n*log_2(n))
,因为它们仅相差一个常数因子,该因子将被吸收Big-O
表示法。
来到你的函数,外循环肯定是 O(n)
但内循环并不完全 log_3(n)
每次。它实际上随着每次迭代而减少。扩展将是:
log_3(n) + log_3(n-1) + log_3(n-2) + ... + log_3(1)
由于上面解释的原因忽略碱基,我们可以写成:
log(n) + log(n-1) + log(n-2) + ... + log(1)
一种评估方法是通过
log(n)
对上述每一项进行上限,即log(n) + log(n-1) + log(n-2) + ... + log(1) <= log(n) + log(n) + log(n) + ... + log(n) <= n*log(n)
因此,复杂度可以写成
O(n*log(n))
.第二种方法如下。重写上面的等式,我们有:
log(n) + log(n-1) + log(n-2) + ... + log(1) = log(n*(n-1)*(n-2)...1) = log(n!)
因此,复杂度当然可以写成
O(log(n!))
。但是log(n!)
呢?根据Stirling's approximation、log(n!) ~ n*log(n) - n + O(log(n))
请注意,根据维基百科:
It is a very powerful approximation, leading to accurate results even for small values of n.
因此,我可以假设对于
n
的大值(我们真正关心的情况),这将非常准确。显然,在上面的近似中,n*log(n)
的值支配其他项,因此,在Big-O
表示法中,我可以写:O(log(n!)) = O(n*log(n))
嵌套循环的时间复杂度等于innermost语句执行的次数。例如:
for ( int i = 1; i <= n; i ++ ) {
for ( int j = 1; j <= n; j ++ ) {
// O(1) expressions
}
}
在这种情况下 (log_3(n)),您可以使用像这样的小 C++ 代码对其进行测试:
int main()
{
const int N = 10;
int j;
int count = 0;
int totalCount = 0;
for ( int i = 1; i <= N; i++ ) {
j = i;
while ( j <= N ) {
j = j * 3;
count++;
}
std::cout << " " << i <<"th iteration of outer loop : inner loop will iterate " << count << " times" << std::endl;
totalCount += count;
count = 0;
}
std::cout << "TOTAL COUNT is : " << totalCount << std::endl;
return 0;
}
你在哪里得到这样的结果:
1th iteration of outer loop : inner loop will iterate 3 times
2th iteration of outer loop : inner loop will iterate 2 times
3th iteration of outer loop : inner loop will iterate 2 times
4th iteration of outer loop : inner loop will iterate 1 times
5th iteration of outer loop : inner loop will iterate 1 times
6th iteration of outer loop : inner loop will iterate 1 times
7th iteration of outer loop : inner loop will iterate 1 times
8th iteration of outer loop : inner loop will iterate 1 times
9th iteration of outer loop : inner loop will iterate 1 times
10th iteration of outer loop : inner loop will iterate 1 times
TOTAL COUNT is : 14
更严格的上限是 O(n)。 因为总时间是 ( Sum(i=1 to n) of (log(n/i)) ) = log(n^n/n!) = O(n) 如果重要的话,运行 时间实际上是 Θ(n)。