找到最高素因子的更优化方法

时间:2015-10-03 18:20:35

标签: java

我已经解决了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);
    }

}
}

2 个答案:

答案 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进行检查。