具有 1 个循环的函数的复杂性
Complexity of a function with 1 loop
谁能告诉我下面这个函数的复杂度是多少?以及如何计算复杂度?
我怀疑它是 O(log(n)) 或 O(sqrt(N))。
我的推理基于以 n=4、n=8、n=16 为例,我发现循环将采用 log(n) 但我认为这还不够,因为 sqrt 也会给出相同的值所以我需要研究更大的 n 值,所以我不确定如何处理这个问题。
今天考试有这个功能
void f(int n){
int i=1;
int j=1;
while(j <= n){
i += 1;
j += i;
}
}
序列 j
经过的是 1 3 6 10 15 21
,又名三角数,又名 n*(n+1)/2
。
展开,这是( n^2 + n ) / 2
。我们可以忽略缩放 ( / 2
) 和线性 ( + n
) 因素,这给我们留下了 n^2
.
j
增长为 n^2
多项式,因此循环将在该增长的倒数后停止:
时间复杂度为O(sqrt(n))
这取决于你的情况。换句话说,时间复杂度是 O(log n)。
相对于输入大小 n,执行了多少条语句?经常,
但并非总是如此,我们可以从循环次数中得到一个想法
迭代。循环体执行 for i= 2^0 + 2^1 + 2^2 + .... + 2^n;还有这个
序列有 O(log n) 个值。
查看 "Introduction to Algorithms" 书中的更多详细信息。
为了它的价值,我编写了一个小程序,试图通过实际计算循环执行的迭代次数来说明这是 O(log(N)) 还是 O(sqrt(N))。这似乎是一个合理的近似值,因为循环体在很大程度上可以忽略不计(只需递增两个整数变量)。
#include <stdio.h>
#include <math.h>
int f(int n)
{
int i=1;
int j=1;
int count = 0;
while(j <= n){
i += 1;
j += i;
count++;
}
return count;
}
int main()
{
for (int ii = 0; ii < 10; ii++) {
int count = pow(10, ii);
int rc = f(count);
char *fmt = "N=%d^%-2d -> %d, log(N)=%.2f, sqrt(N)=%.2f\n";
printf(fmt, 10, ii, rc, log(count), sqrt(count));
}
return 0;
}
运行 此代码产生以下输出:
N=10^0 -> 1, log(N)=0.00, sqrt(N)=1.00
N=10^1 -> 4, log(N)=2.30, sqrt(N)=3.16
N=10^2 -> 13, log(N)=4.61, sqrt(N)=10.00
N=10^3 -> 44, log(N)=6.91, sqrt(N)=31.62
N=10^4 -> 140, log(N)=9.21, sqrt(N)=100.00
N=10^5 -> 446, log(N)=11.51, sqrt(N)=316.23
N=10^6 -> 1413, log(N)=13.82, sqrt(N)=1000.00
N=10^7 -> 4471, log(N)=16.12, sqrt(N)=3162.28
N=10^8 -> 14141, log(N)=18.42, sqrt(N)=10000.00
N=10^9 -> 44720, log(N)=20.72, sqrt(N)=31622.78
所以,比如你可以看到,当N=10^9时,迭代次数为44720,比log(N)(20.72)大很多,但很接近sqrt(N)(31622.78) ).
谁能告诉我下面这个函数的复杂度是多少?以及如何计算复杂度?
我怀疑它是 O(log(n)) 或 O(sqrt(N))。 我的推理基于以 n=4、n=8、n=16 为例,我发现循环将采用 log(n) 但我认为这还不够,因为 sqrt 也会给出相同的值所以我需要研究更大的 n 值,所以我不确定如何处理这个问题。
今天考试有这个功能
void f(int n){
int i=1;
int j=1;
while(j <= n){
i += 1;
j += i;
}
}
序列 j
经过的是 1 3 6 10 15 21
,又名三角数,又名 n*(n+1)/2
。
展开,这是( n^2 + n ) / 2
。我们可以忽略缩放 ( / 2
) 和线性 ( + n
) 因素,这给我们留下了 n^2
.
j
增长为 n^2
多项式,因此循环将在该增长的倒数后停止:
时间复杂度为O(sqrt(n))
这取决于你的情况。换句话说,时间复杂度是 O(log n)。 相对于输入大小 n,执行了多少条语句?经常, 但并非总是如此,我们可以从循环次数中得到一个想法 迭代。循环体执行 for i= 2^0 + 2^1 + 2^2 + .... + 2^n;还有这个 序列有 O(log n) 个值。
查看 "Introduction to Algorithms" 书中的更多详细信息。
为了它的价值,我编写了一个小程序,试图通过实际计算循环执行的迭代次数来说明这是 O(log(N)) 还是 O(sqrt(N))。这似乎是一个合理的近似值,因为循环体在很大程度上可以忽略不计(只需递增两个整数变量)。
#include <stdio.h>
#include <math.h>
int f(int n)
{
int i=1;
int j=1;
int count = 0;
while(j <= n){
i += 1;
j += i;
count++;
}
return count;
}
int main()
{
for (int ii = 0; ii < 10; ii++) {
int count = pow(10, ii);
int rc = f(count);
char *fmt = "N=%d^%-2d -> %d, log(N)=%.2f, sqrt(N)=%.2f\n";
printf(fmt, 10, ii, rc, log(count), sqrt(count));
}
return 0;
}
运行 此代码产生以下输出:
N=10^0 -> 1, log(N)=0.00, sqrt(N)=1.00
N=10^1 -> 4, log(N)=2.30, sqrt(N)=3.16
N=10^2 -> 13, log(N)=4.61, sqrt(N)=10.00
N=10^3 -> 44, log(N)=6.91, sqrt(N)=31.62
N=10^4 -> 140, log(N)=9.21, sqrt(N)=100.00
N=10^5 -> 446, log(N)=11.51, sqrt(N)=316.23
N=10^6 -> 1413, log(N)=13.82, sqrt(N)=1000.00
N=10^7 -> 4471, log(N)=16.12, sqrt(N)=3162.28
N=10^8 -> 14141, log(N)=18.42, sqrt(N)=10000.00
N=10^9 -> 44720, log(N)=20.72, sqrt(N)=31622.78
所以,比如你可以看到,当N=10^9时,迭代次数为44720,比log(N)(20.72)大很多,但很接近sqrt(N)(31622.78) ).