62,614
社区成员
发帖
与我相关
我的任务
分享
public class MyTest{
public static void main(String[] args){
int[] a=eg1(18,10);
if(a==null){ //找不到返回了null;
System.out.println("找不到合适的结果!");
System.exit(0);
}
for(int i=0;i<a.length;i++){
System.out.println(a[i]+" ");
}
}
public static int[] eg1(int n,int leng){ //把原来的l改为leng,避免和数字1混淆。
int[] result=null;
int len=leng;
while(len<n){
if(2*n/len*len==2*n && (2*n/len+1-len)%2==0){ //这里原来是2*n/len*len==2*n || (2*n/len+1-len)%2==0 错了。
break;
}
len++;
}
if(len>=n|| 2*n/len-len+1<0) return result;
result=new int[len];
int start=(2*n/len-len+1)/2;
int end=start+len-1;
for(int i=start,j=0;i<=end;i++){
result[j++]=i;
}
return result;
}
}
//以下是思路:
//假设从自然数x开始有L个连续的自然数之和为N,则由等比数列求和公式得:(x+x+L-1)*L/2=N;由于x,L,N都是整数,所以2*N应该能被L整除。
//由上式可得:x=((2*N)/L-L+1)/2,由此可见,如果L和N是确定的,x就是确定的。
//由以上两点,只要2*N能被L整除,同时2*N/L-L+1能被2整除,就有一个长度为L且从x开始的自然数序列之和为N。
//编程就简单了,让len从L开始递增,看看2*N能不能被len整除,同时,2*N/len-len+1能不能被2整除。如果都能,则用上面的公式求出x(程序中的start)
//由于求的最小一个序列,所以只要找到一个len就结束了。
/**
*
*/
package resume.csdn;
/**
* @author lang3879
*
*/
public class ArrayEqualsSum {
public int[] mainGenerateArray(int sum, int length) {
int[] returnMe = this.generateArray(sum, length);
// ↓length的长度不知道如何判断,根据sum好像判断不出
// 比如sum=0,length=3,返回[-1,0,1]
while (length < 20 && returnMe.length == 0) {
length++;
returnMe = this.generateArray(sum, length);
}
return returnMe;
}
/**
* 假设起始为x,长度为3; x+(x+1)+(x+2)=3*x+(0+1+2)=sum 所以x=(sum-(0+1+2+...))/length
*
* @param sum
* 和的值
* @param length
* 数组的长度
* @return
*/
public int[] generateArray(int sum, int length) {
// iSum=(0+1+2+...)
int iSum = 0;
int iStartNumber = 0;
final int startAddEnd = (iStartNumber + (iStartNumber + length - 1));
if (length % 2 == 0) {// 表示偶数,首尾相加并乘以长度的一半
iSum = startAddEnd * (length / 2);
} else {// 表示奇数,首尾相继并乘以长度-1的一半,再加中间的那一个元素
iSum = startAddEnd * ((length - 1) / 2) + startAddEnd / 2;
}
// ↓整除标出x存在
if ((sum - iSum) % length == 0) {
return this.repateNumber((sum - iSum) / length, length);
}
return new int[] {};
}
/**
* 创建startNumber开始长度为length,元素间递增为一的数组
*
* @param startNumber
* @param length
* @return
*/
private int[] repateNumber(int startNumber, int length) {
int[] returnMe = new int[length];
for (int index = 0; index < length; index++) {
returnMe[index] = startNumber;
startNumber++;
}
return returnMe;
}
/**
* int数组转字符串
*
* @param intArray
* @return
*/
private String intArrayToString(int[] intArray) {
StringBuffer sb = new StringBuffer("[");
for (int index = 0; index < intArray.length; index++) {
int i = intArray[index];
sb.append(i).append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
/**
* 写一个类,实现这样一个方法,此方法给定两个参数N、L(均为整数), N是一个自然数,L表示一个长度。 要求此函数输出一个最小长度的连续数的数组,
* 此数组的几个连续数的和要等于给定的N, 并且该数组的长度要大于等于给定的L。 如没有满足该条件的则返回一个空数组{}。
* eg1:(18,3)则应该return {5,6,7};
* 分析满足和为18的连续数的数组有两个:{3,4,5,6}、{5,6,7}应题目要求输出最短的数组,所以结果如上。 eg2: (18,4)
* 则应该返回结果{3,4,5,6}; eg3: (45,10)则返回结果为{0,1,2,3,4,5,6,7,8,9};
*
* @param args
*/
public static void main(String[] args) {
final ArrayEqualsSum arrayEqualsSum = new ArrayEqualsSum();
System.out.println(arrayEqualsSum.intArrayToString(arrayEqualsSum
.mainGenerateArray(18, 3)));
System.out.println(arrayEqualsSum.intArrayToString(arrayEqualsSum
.mainGenerateArray(0, 3)));
System.out.println(arrayEqualsSum.intArrayToString(arrayEqualsSum
.mainGenerateArray(45, 10)));
}
}