我已经解决了Project Euler#3,但在黑客等级中解决了同样的问题,其时间限制为< 4秒不起作用。我已经尝试使用平方根解决方案来加速,但它失败了。
示例:
10000001的素因子是11和909091,我们有sqrt(10000001)= 3162,如果我们检查从2到3162的所有素数,我们只能有11,在循环终止后,结果将是11,答案不正确
因此,当我使用num / 2时,运行时间显着增加。
public class Solution {
static boolean checkPrime(long num){
boolean toret = true;
long sq = (long) Math.sqrt(num);
for(long i=2; i<=sq; i++){
if(num%i ==0)
toret = false;
}
return toret;
}
static long gimmeAns(long num){
ArrayList<Long> al = new ArrayList<Long>();
int q = 0;
long[] list = new long[10];
long sq = (long)Math.sqrt(num);
long sqint;
boolean flag = true;
if(num < 0){
for(long i =3; i<=num; i+=2){
if(num%i == 0)
al.add(i);
}
}else{
//for(long i =3; i<=sq; i+=2){
//if(num%i == 0)
//al.add(i);
//}
boolean isPrimeCheck = checkPrime(num);
if(isPrimeCheck){
al.add(num);
}
for(long i =3 ; i<= num/2 ; i+=2){
if(num%i==0){
al.add(i);
}
}
}
Iterator it = al.iterator();
while(it.hasNext()){
long curr = (long) it.next();
flag = true;
long squrt = (long) Math.sqrt(curr);
for(long i=2; i<=squrt; i++){
if(curr%i == 0)
flag = false;
}
if(flag == true){
list[q++] = curr;
}
}
return list[q-1];
}
public static void main(String[] args) {
long numberCases;
Scanner in = new Scanner(System.in);
numberCases = in.nextLong();
long result = 0;
for(long i=0; i< numberCases; i++){
long num = in.nextLong();
result = gimmeAns(num);
System.out.println(result);
}
}
}
答案 0 :(得分:1)
如何迭代所有 sqrt(n)数字。每次找到素数时,都将数字除以该素数(并且不增加数量)。
现在,当您到达 sqrt(n)时,将最新找到的分隔符与剩余数字进行比较。您必须返回两者中的最大值:
long n = sc.nextLong();
int k = 0x02;
int l = (int) (Math.sqrt(n)+1);
while(k < n && k <= l) {
if(n%k == 0) {
n /= k;
} else {
k++;
}
}
return Math.max(n,k);
在这种情况下,如果数字有两个素数,则较小的素数将在while循环中捕获,导致n
现在具有更大的值。
答案 1 :(得分:0)
一种简单的方法是向后检查数字。您应该尝试从3162到2进行检查,而不是从2到3162进行检查。