最大数量的连续奇数整数以达到目标

时间:2015-10-13 21:17:00

标签: java algorithm

我目前正在寻找最大数量的连续奇数整数加在一起以等于目标数。

我目前找到3个连续整数的代码看起来像

public class consecutiveOdd {
    public static void main(String[] args){
        int target = 160701;
        boolean found = false;

        for(int i = 1; i < target; i++){
            if(i + (i+2) + (i+4) == target){
                System.out.print(i + " + " + (i+2) + " + " + (i+4));
                found = true;
            }

         }
         if(!found){
            System.out.println("Sorry none");
         }
     }
}

我认为需要一个while循环来构建(i + 2)增量的迭代,但是在开发正确的算法时遇到了麻烦。任何帮助或提示将不胜感激!

最佳, Otterman

3 个答案:

答案 0 :(得分:3)

看模式:

  1. 对于1个和,i = target
  2. 对于2个加数,等式为2*i + 2 = target,因此i = (target - 2) / 2
  3. 对于3个加数,等式为3*i + 6 = target,因此i = (target - 6) / 3
  4. 对于4个加数,等式为4*i + 12 = target,因此i = (target - 12) / 4
  5. 等。显然i在所有情况下都必须是一个奇数。

    您可以计算出n加法的一般表达式,并简化它以向您显示算法,但您可能已经能够看到算法......

    申请@ rossum的建议:

    1. 对于1个和,2m + 1 = target
    2. 对于2个加号,2m + 1 = (target - 2) / 2m = (target - 4) / 4
    3. 对于3个加号,2m + 1 = (target - 6) / 3m = (target - 9) / 6
    4. 对于4个加号,2m + 1 = (target - 12) / 4m = (target - 16) / 8

答案 1 :(得分:3)

让我们说答案等于k (k > 0)。然后对于一些奇怪的i我们可以写:i + (i + 2) + (i + 4) + ... + (i + 2k - 2) = target。您可以看到这是arithmetic progression的总和,因此您可以使用众所周知的公式来计算它。应用公式我们可以得到: i = target/k - k + 1

基于这个公式,我建议使用以下算法:

  1. 迭代k
  2. 的值
  3. 如果target/k - k + 1是正奇数,请更新答案。
  4. 简单实施。

    int answer = -1;
    for (int k = 1;; k++) {
        int i = target / k - k + 1;
        if (i <= 0) {
            break;
        }
        // Check if calculated i, can be the start of 'odd' sequence.
        if (target % k == 0 && i % 2 == 1) {
            answer = k;
        }
    }
    

    此算法的运行时间为O(sqrt(target))

答案 2 :(得分:0)

n奇数整数序列的总和,可以计算为平均值(中点m)乘以值的数量(n),所以:

sum  =  5 + 7 + 9       =  m * n  =  7 * 3  =  21
sum  =  5 + 7 + 9 + 11  =  m * n  =  8 * 4  =  32

如果n为奇数,则m为奇数,如果n为偶数,则m为偶数。

序列的firstlast个数字可以计算为:

first  =  m - n + 1  =  8 - 4 + 1  =  5
last   =  m + n - 1  =  8 + 4 - 1  =  11

其他有趣的公式:

m  =  sum / n
m  =  (first + last) / 2
last  =  first + (n - 1) * 2  =  first + 2 * n - 2
m  =  (first + first + 2 * n - 2) / 2  =  first + n - 1

最长的序列必须以尽可能低的first值开头,这意味着1,所以我们得到:

sum  =  m * n  =  (first + n - 1) * n  =  n * n

这意味着任何给定sum的最长序列最多只能sqrt(sum)长。

首先从sqrt(sum)开始,然后向下搜索,直到找到有效的n

/**
  * Returns length of sequence, or 0 if no sequence can be found
  */
private static int findLongestConsecutiveOddIntegers(int sum) {
    for (int n = (int)Math.sqrt(sum); n > 1; n--) {
        if (sum % n == 0) { // m must be an integer
            int m = sum / n;
            if ((n & 1) == (m & 1)) // If n is odd, mid must be odd. If n is even, m must be even.
                return n;
        }
    }
    return 0;
}

结果:

n  =  findLongestConsecutiveOddIntegers(160701)  =  391
m  =  sum / n  =  160701 / 391  =  411
first  =  m - n + 1  =  411 - 391 + 1  =  21
last   =  m + n - 1  =  411 + 391 - 1  =  801

sqrt(160701) = 400.875...以来,结果在 10 次迭代(400到391,包括400和391)中找到。

结论:

最大连续奇数整数等于160701: 391

21 + 23 + 25 + ... + 799 + 801 = 160701