这个算法的时间复杂度是多少,每个素数都可以找到n

时间:2012-05-03 05:38:35

标签: algorithm complexity-theory primes

这是有问题的算法,伪代码:

list.add(2)
for (i = 3 to n)
    isPrime=true
    for each (j in list)
        if ((i mod j) = 0)
            isPrime=false
            break
    if (isPrime)
        list.add(i)
return list

我的TA今天告诉我这个算法的复杂度为O(n ^ 2),但我很确定这是不正确的,特别是考虑到任何n都有大约n / ln(n)素数,因此,如果n本身是素数,则内循环在其最后一次迭代中不会迭代超过n / ln(n)次。但是我认为它实际上低于O(n ^ 2 / ln(n)),但我不确定如何确定它实际上是什么。例如,每个偶数只迭代第二个循环两次。

2 个答案:

答案 0 :(得分:1)

n个数字中,您正在检查是否为素数,实际上有大约n / ln(n)个素数,这要求所有i / ln(i)已找到的素数作为除数进行尝试。因此,算法的复杂性为W(n^2 / ln(n)^2)W为big-omega)和O(n^2 / ln(n)n^2 / ln(n)^2的增长速度比n * sqrt(n)增长得快。

要达到O(n * sqrt(n))时间复杂度,您应该使用以下伪代码:

list.add(2)
for (i = 3 to n)
    isPrime=true
    for each (j in list)
        if j > sqrt(i)
            break
        if ((i mod j) = 0)
            isPrime=false
            break
    if (isPrime)
        list.add(i)
return list

答案 1 :(得分:0)

复杂性为O((n/log(n))**2)

您可以按如下方式进行分析。您遇到两组数字,素数和复合数。

你有O(n/log(n))个素数,每个素数必须针对所有较小素数进行测试,每个素数O(n/log(n))工作,总共O((n/log(n))**2)次。

你有O(n - n/log(n)) = O(n)个复合材料,每个复合材料必须在sqrt(n)以下的某些素数子集上进行测试,以便O(sqrt(n))以上的工作进行测试,因此总工作量高于O(n sqrt(n))

因此,O((n/log(n))**2)一词占主导地位。

当然,这不是你的直觉导致你的答案。如果你聪明的话,你试图获得直觉,并在素数平方超过你的目标数时切断内循环,然后需要多长时间?结果是O(n sqrt(n) / (log(n))**2)。原因是O(sqrt(n)/log(sqrt(n)) = O(sqrt(n)/log(n))下面有sqrt(n)个素数,每个素数都需要针对O(n/log(n))个数字进行测试(请参阅http://mathworld.wolfram.com/MertensTheorem.html以了解为什么会这样)。

然而,在这一点上,我们已经从算法世界传递到数论世界。 :d