我有以下问题:
假设通过添加2个素数可以获得大于4的偶数
数字,我必须编写一个检查它的算法。该算法应该花费更少的时间O(n ^ 2)。
例如,有一组从6到n的数字。如果我们有数字6,答案是6 = 3 + 3和22 = 17 + 5,依此类推。
我的第一个想法:
S - set of n numbers
for i=1 to n {
//removing odd numbers
if (S[i]%2!=0)
continue;
result = false;
for j=2 to S[i]-2{
if (j.isPrime) // prime test can be done in O(log^2(n))
if ((S[i]-j).isPrime)
result = true;
break;
else
continue;
}
if (result == false)
break;
}
由于我使用2个for循环,因此该算法的总运行时间应为
O(n*n)*O(log^2(n)) = O(n^2*log^2(n))
不小于O(n^2)
。
有没有人有想法缩短运行时间以获得小于O(n^2)
的所需时间?
答案 0 :(得分:2)
如果set包含大数字,我什么都没有。
如果max(S)< n ^ 2 / log(n)比:
您应该预处理区间[1,max(S)]中的哪些数字是素数。 对于预处理,您可以使用sieve of Eratosthenes
然后,您可以检查数字是否为O(1)中的素数,并且解决方案的复杂性变为O(N ^ 2)。
答案 1 :(得分:1)
这是Goldbach's conjecture。已知原始性测试在 P (多项式时间),但收支平衡高得离谱 - 在实践中,你将无法在 O附近的任何地方做到这一点(n ^ n ^ 2)强>
如果我们假设您只需要处理相对较小的数字,并且可以预先计算质数达到一定限度,那么您仍然需要找到候选对。素数计数函数给出大约:n / ln(n)
素数,小于(n)
。从(p)
中减去候选素数(n)
会得到一个奇数(q)
。如果您可以查找复杂度为(q)
的{{1}}的素数,或者更好 - 例如,所有的 O(1)查找表奇数小于极限 - 你可以达到 O(n ^ 2)或更好。
答案 2 :(得分:0)
你只能运行到N的平方根,这足以确定数字是否为素数 这会减少你的运行时间。
还要看一下以下问题 - Program to find prime numbers