【问题标题】:Complexity of a function with 1 loop具有 1 个循环的函数的复杂性
【发布时间】:2021-12-16 09:44:26
【问题描述】:

谁能告诉我以下函数的复杂性是什么?以及如何计算复杂度?

我怀疑它是 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;
     }
}

【问题讨论】:

  • 我的意思是我的猜测是 O(log(n)) 或 O(sqrt(n)) 不是我不记得答案 xD
  • 陈述你的理由并询问你是否正确。这通常会得到一个更有利的结果,因为如果您不正确,我们可以纠正您推理中的错误,以免再次发生。
  • 我的推理是基于以 n=4、n=8、n=16 为例,我发现循环将采用 log(n) 但我认为这还不够因为 sqrt 也会给出相同的值,所以我不知道如何处理这个:/
  • 提示:j 遵循Triangular numbers 的模式。
  • 是的,我想通了,但我仍然不确定如何从那里获得复杂性

标签: c++ algorithm time-complexity big-o


【解决方案1】:

为了它的价值,我编写了一个小程序,试图通过实际计算循环执行的迭代次数来说明这是 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) 非常接近。

【讨论】:

    【解决方案2】:

    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))

    【讨论】:

    • 很好理解,谢谢。
    【解决方案3】:

    这取决于你的情况。换句话说,时间复杂度是 O(log n)。 相对于输入大小 n,执行了多少条语句?经常, 但并非总是如此,我们可以从循环次数中得到一个想法 迭代。循环体执行 i= 2^0 + 2^1 + 2^2 + .... + 2^n;和这个 序列有 O(log n) 个值。

    查看"Introduction to Algorithms" 书籍了解更多详情。

    【讨论】:

    • i seq 是1 2 3 4 ..,j seq 是1 3 6 10 15 21 ...。没有2^0 2^1 ... 2^n 序列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多