【问题标题】:Largest Divisor of N (Excluding Itself)N 的最大除数(不包括它自己)
【发布时间】:2017-06-09 15:11:27
【问题描述】:

我正在尝试将列表划分为尽可能大的子列表。如果列表不能以这种方式进行划分,我将根据需要进行处理,但我需要获得除 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; 
}

【问题讨论】:

标签: java int division modulus


【解决方案1】:

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

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;
}

【讨论】:

  • 比原来的要快,但不如其他方法快。
【解决方案2】:

你知道如果a能被b整除,那么它也能被a/b和更小的b是,较大的是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) 放弃了。

所以最有效的方法是:

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; 
}

【讨论】:

    【解决方案3】:

    我不知道你是否可以在恒定时间内做到这一点,但你肯定可以在比这更短的时间内做到这一点。

    从 2 开始,遍历所有数字,检查 n 是否能被那个数字整除。当你得到一个除以 n 的数字时,你可以停下来——你的答案是 n/i。如果你到最后它仍然没有除,那么 n 是素数,答案就是 1。

    如果没有找到除数,不用在n/2结束,可以用这个方法在√n结束,这样可以减少大O。

    另外,您可以先检查它是否能被 2 整除,然后转到 3,只检查从那里开始的奇数。 (如果它可以被偶数整除,那么它就可以被 2 整除。)这不会改变大 O,但它应该将处理时间几乎减少一半,因为你只检查了大约一半的除数。

    【讨论】:

    • 事实上,你可以只检查它是否能被素数整除并跳过任何非素数。问题是计算哪些数字是素数比它节省的工作更多,所以除非你碰巧有一个你的程序可以使用的素数列表,否则它可能不值得。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 2021-04-24
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多