N的最大除数(不包括在内)

时间:2017-01-24 17:32:31

标签: java int division modulus

我正在尝试将列表划分为尽可能大的子列表。如果列表不能以这种方式划分,我将根据需要处理它,但我需要获得除N本身之外的最大数量,均匀地划分N.

我写了一个非常天真的解决方案,但我觉得应该有一个公式或者其他东西可以在不变的时间内完成。我的列表不是那么大,最大大小是1000.这可能不是关键路径,但有更好的算法吗?

public static int largestDivisor(int n){
   int divisor = 0;
   for (int i = 1; i <= n/2; i++)
       if (n % i == 0) 
           divisor = i;

   return divisor; 
}

3 个答案:

答案 0 :(得分:4)

反向迭代值。只需返回您找到的第一个(它将是最好的)。像,

public static int largestDivisor(int n) {
    for (int i = n / 2; i >= 2; i--) {
        if (n % i == 0) {
            return i;
        }
    }
    return 1;
}

或者,您可能会对@WillemVanOnsemanswer进行略微改进,并以奇数值开头,例如;

public static int largestDivisor(int n) {
    if (n % 2 == 0) {
        return n / 2;
    }
    final int sqrtn = (int) Math.sqrt(n);
    for (int i = 3; i <= sqrtn; i += 2) {
        if (n % i == 0) {
            return n / i;
        }
    }
    return 1;
}

答案 1 :(得分:1)

你知道如果 a 可以通过 b 分割,它也可以通过 a / b 分割,而较小的 b < / em>是, a / b 越大,所以一旦找到了除数,就返回n/divisor

public static int largestDivisor(int n){
    for(int i = 2; i <= n/2; i++)
        if(n % i == 0) {
            return n/divisor;
        }
    }
    return 0; //or whatever you decide to return if there is no such divisor
}

这也更快,因为:

  1. 除数越多,得分就越小;和
  2. 您已经可以放弃sqrt(n)
  3. 所以最有效的方法是:

    public static int largestDivisor(int n){
        int sqrtn = (int) Math.sqrt(n);
        for(int i = 2; i <= sqrtn; i++)
            if(n % i == 0) {
                return n/divisor;
            }
        }
        return 0; 
    }

答案 2 :(得分:1)

我不知道你是否可以在不变的时间内完成这项工作,但你可以在比这更短的时间内完成这项工作。

从2开始,遍历所有数字,检查n是否可以被该数字整除。当你得到一个除以n的数字,那么你可以停止 - 你的答案是n / i。如果你走到尽头但它仍然没有分裂,那么n是素数,答案只有1。

如果你没有找到除数,而不是以n / 2结尾,你可以用这种方法结束√n,这将减少大O.

此外,您可以先检查它是否可被2整除,然后转到3并仅检查那里的奇数。 (如果它被一个偶数整除,则它可以被2整除。)它不会改变大O,但它应该将处理时间减少一半,因为你只检查了大约一半除数。