如何在循环内使用扩展数组(本身是循环的)来计算算法的运行时间?

时间:2019-01-01 11:04:36

标签: time-complexity

我有一种算法可以找到N下的素数列表,以及所有数字N中的最低因子

/*
arrLF stands for arrLowestFactor, it stores all the LF
arrPrime is the list of primes under N. The variable pn is used to keep track of how many primes we have discovered. Initially pn is zero.
*/
for(int i = 2; i <= N; i++){
     //if a number i hasn't got its lowest factor yet, it means we have discovered a new prime number. And this prime number will be the LF of i too.
    if(!arrLF[i]){
        arrPrime[pn++] = i;
        arrLF[i] = i;
    } 

    //run through the list of prime once and fill up the lowest factor of (i * arrPrime[j]) in the arrLF table 
    //it's like doing sieve of eratosthenes but we build the table up one at a time
    for(int j = 1; i * arrPrime[j] <= N; j++){
        arrLF[ i * arrPrime[j] ] = arrPrime[j];
        if( i % arrPrime[j] == 0)
            break;
    }
}

对于外循环,它以O(N)运行。因此,该算法的运行时间为O(N * M),其中M是内部循环的运行时间。但是由于质数的列表不一致地扩展,我如何评估M的复杂度?

顺便说一句,我是通过研究codeforce上的红色编码器的解决方案找到了该算法的,有人知道这个算法或其名称吗?

1 个答案:

答案 0 :(得分:1)

您的算法将在O(n)中运行。让我解释一下原因

我们需要查看内部循环,以了解为什么它不以指数方式影响时间复杂度。

内部循环外观将在最坏的情况下每次迭代运行以下次数

第一次迭代:1/2 * N次

第二次迭代:1/3 * N次

第3次迭代:1/4 * N次

以此类推

因此,每次执行此操作时,内循环运行的次数都会减少。

我们可以说内循环运行的总次数是 SUM(1/2 + 1/3 + 1/4 + ... 1 / N)

这称为谐波序列 https://en.wikipedia.org/wiki/Harmonic_series_(mathematics)

尽管该级数收敛到无穷大,但收敛很慢,对于10 ^ 43的N来说它小于100

因此,实际上,内部循环将在最坏的情况下运行恒定的N次,比如说Java浮动限制的最大值为100倍

所以这意味着完整算法的时间复杂度是内部循环的时间复杂度,因为外部循环不会运行任何其他循环。 因此,时间复杂度将为O(Xn),其中X为常数,正如我们所解释的,在Java的数字范围内,它实际上不会超过100或200。这将意味着算法的总复杂度为O(n),因为我们省略了常量