Java 等于目标的最大连续奇数整数数
我目前正在寻找最大数量的连续奇数加起来等于一个目标数 我当前查找3个连续整数的代码如下所示Java 等于目标的最大连续奇数整数数,java,algorithm,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)
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");
}
}
}
公共类连续奇数{
公共静态void main(字符串[]args){
int目标=160701;
布尔值=false;
for(int i=1;i
我认为需要进行(I+2)增量的while循环构建迭代,但在开发正确的算法时遇到了困难。任何帮助或提示都将不胜感激
最好的,
水獭查看图案:
i=target
2*i+2=target
,因此i=(target-2)/2
3*i+6=target
,因此i=(target-6)/3
4*i+12=target
,因此i=(target-12)/4
显然,
i
在所有情况下都必须是奇数整数
您可以计算出n
summands的一般表达式,并对其进行简化以向您展示一个算法,但您可能已经能够看到一个算法
应用@rossum的建议:
2m+1=目标
2m+1=(目标-2)/2
,因此m=(目标-4)/4
2m+1=(目标-6)/3
,因此m=(目标-9)/6
2m+1=(目标-12)/4
,因此m=(目标-16)/8
假设答案等于
k(k>0)
。然后对于一些奇怪的i
我们可以写:i+(i+2)+(i+4)+(i+2k-2)=目标
。你可以看到这是的和,所以你可以用一个众所周知的公式来计算它。应用公式,我们可以得到:
i=target/k-k+1
基于此公式,我建议采用以下算法:
k的值
target/k-k+1
为正奇数整数,则更新答案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;
}
}
int-answer=-1;
for(int k=1;k++){
int i=目标/k-k+1;
如果(i一系列n
奇数整数之和可以计算为平均值(中点m
)乘以值的数量(n
),那么:
如果n
为奇数,则m
为奇数;如果n
为偶数,则m
为偶数
序列的第一个
和最后一个
编号可计算为:
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)
long
因此,从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;
}
结果:
由于sqrt(160701)=400.875…
,结果在10次迭代(400到391次,包括400到391次)中找到
结论:
等于160701的最大连续奇数整数:391
21 + 23 + 25 + ... + 799 + 801 = 160701
for循环将查看奇数集{1,3,5},但也会查看偶数集{2,4,6}因此,你可能想说i+=2而不是i++。顺便说一句,我喜欢上面的数学解,而不是蛮力搜索。仅供参考:答案是391:21+23+25+…+799+801=160701
嘿,谢谢大家!显然i
在所有情况下都必须是奇数。根据问题,使用替换i=2m+1
并求解m
以放宽要求。这样m
可以是奇数也可以是偶数。@rossum整洁的建议,我已将其添加到答案中。
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
21 + 23 + 25 + ... + 799 + 801 = 160701