如何在O(n)时间复杂度中实现橡皮擦筛?

问题描述 投票:-1回答:2

此算法的实现是在O(n*log(log(n))时间复杂度中找到最高达N的素数。如何达到O(n)时间复杂度?

algorithm primes primality-test
2个回答
1
投票
您可以在[2, n]时间中执行Eratosthenes筛分以确定在O(n)范围内哪些数字是质数:

  • 对于间隔x中的每个数字[2, n],我们计算x的最小素数。为了实现目的,可以通过保留一个数组-MPF[]-来轻松实现,其中MPF[x]表示x的最小素数。最初,应将每个整数MPF[x]x设置为零。随着算法的进行,该表将被填充。
  • 现在,我们使用一个for循环,并从i = 2迭代到i = n(含)。如果我们遇到一个MPF[i]等于0的数字,那么我们会立即得出结论i是质数,因为它没有最小质数因数。此时,通过将i插入列表将其标记为素数,并将MPF[i]设置为等于i。相反,如果MPF[i]确实等于0,则我们知道i是合成的,其最小素数等于MPF[i]

    在每次迭代中,我们检查MPF[i]后,执行以下操作:为小于或等于y_j = i * p_j的每个素数p_j计算数字MPF[i],并将MPF[y_j]设置为等于到p_j

  • 这似乎违反直觉---如果我们有两个嵌套循环,为什么运行时O(n)?关键思想是每个值都设置为正好一个,因此运行时间为O(n)。这个website提供了一个C ++实现,我在下面提供了它:

const int N = 10000000; int lp[N+1]; vector<int> pr; for (int i=2; i<=N; ++i) { if (lp[i] == 0) { lp[i] = i; pr.push_back (i); } for (int j=0; j<(int)pr.size() && pr[j]<=lp[i] && i*pr[j]<=N; ++j) lp[i * pr[j]] = pr[j]; }

以上实现中的数组lp[]与我在解释中描述的MPF[]相同。另外,pr存储质数列表。


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.