题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
思路分析
方法一:注意到序列为连续且递增为1,构造高低字位,low,high,代表首项及末项,项数即为high-low+1,即可求出总和,总和小于sum,high自增,大于sum,low自增,等于时,返回此序列。此种方法无需太多数学思想,符合程序员的暴力美学哈
方法二:由(a1+an)*n=s,可知 n<sqrt(2s);
序列中间值,代表序列就要区分平均值,但序列个数不确定,所以就要区分奇数偶数的区别了;
序列长度为n,中间值为s/n,由此可得到这组序列
代码
方法一
import java.util.ArrayList;
public class Solution {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
if (sum<3){
return res;
}
int low = 1;
int high = 2;
while (high>low) {
int sum1 = (low+high) * (high-low+1) / 2;
if (sum1 < sum) {
high++;
}
if (sum1 > sum) {
low++;
}
if (sum1 == sum) {
addresult(low,high);
low++;
}
}
return res;
}
void addresult (int low, int high){
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = low; i <=high; i++) {
arrayList.add(i);
}
res.add(arrayList);
}
}
结果
方法二:
public static ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
if (sum<3) {
return res;
}
for (int n = (int)Math.sqrt(2*sum); n >=2; n--) {
if (n%2==1 && sum%n==0 || n%2==0 && sum%n*2==n) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int j = 0,k= (sum/n)-(n-1/2); j<n; k++,j++) {
arrayList.add(k);
}
res.add(arrayList);
}
}
return res;
}