c - O(n^2) 的时间复杂度

标签 c complexity-theory

void f(int n)
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n * n / i; j += i)
            printf(“*”);
}

这段代码的时间复杂度是多少? 我认为它会是 O(n3) 但结果实际答案是 O(n2)我不知道为什么。 有人可以解释吗? (有可能是考试出错)

最佳答案

关于内循环有两点需要注意:

  1. 这里的“除以 i”:j<=n*n/i

  2. 此处的“增量为 i”:j+=i (这给出了另一个“除以 i )

考虑到这一点,我们可以看到内部循环执行多少次取决于 i 的值。 :

i = 1 --> n*n/1/1

i = 2 --> n*n/2/2

i = 3 --> n*n/3/3

i = 4 --> n*n/4/4

....

然后求和:

n*n/1/1 + n*n/2/2 + n*n/3/3 + n*n/4/4 + ...

这是:

n*n/1^2 + n*n/2^2 + n*n/3^2 + n*n/4^2 + ...

这是:

n^2 * (1/1^2 + 1/2^2 + 1/3^2 + 1/4^2 + ... )

根据https://en.wikipedia.org/wiki/Basel_problem这是大约:

n^2 * 1.644934

所以复杂度是O(n^2)

只是为了好玩,下面的代码计算了内部循环的执行次数

#include <stdio.h>

unsigned long long  f(int n)
{
    unsigned long long c = 0;
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n*n/i; j+=i)
        {
            ++c;
        }
    }
    return c;
}

void g(int n)
{
    unsigned long long c = f(n);
    printf("d=%-10d c=%-10llu c/n^2=%f\n", n, c, (((double)c)/n/n));
}

int main()
{
    g(10);
    g(100);
    g(1000);
    g(10000);
    return 0;
}

输出:

d=10         c=157        c/n^2=1.570000
d=100        c=16395      c/n^2=1.639500
d=1000       c=1644474    c/n^2=1.644474
d=10000      c=164488783  c/n^2=1.644888

关于c - O(n^2) 的时间复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72700756/

相关文章:

c - 嵌入时如何使用LuaJIT的ffi模块?

c - 某些 .c 文件的一个 header 会导致链接器错误

c - 向指针地址添加 0 填充

java - 计算字符串中最长的回文子串

algorithm - 当 c > 0 Log(n) = O(n) 时?不确定为什么不是 O(log n)

c - C 中的多客户端聊天服务器 - 执行问题

c - 矩阵转置在 C 中发送错误

c++ - Top K 最小选择算法 - O (n + k log n) 与 O (n log k) for k << N

c - 循环的时间复杂度

algorithm - 代入求解递归方程