和为S的连续整数序列。感觉是找规律系列,有点绕

题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

思路

这些连续的正数序列,前后组成一对,一组之和是S的因子。 从连续序列的长度入手,长度记为i:
若长度是奇数,如果能整除S=100,说明S/i的结果就在连续序列的正中间,向前向后的数分别成组。如S=100,i=5,S/i=100/5=20,那么20是这个长度为5的序列中间数,19+21=40,18+22=40,这五个数组是一个连续序列。
若长度是偶数,即是有i/2个组,若S能整除组数,并且每组数值之和为奇数,那么可以组成连续序列。
满足的例子:长度i=8,有4组,每组和为25。那么这个序列的中间数可以看成是25/2=12(实质上是12和13)。另外三组也可向前向后成组。
不满足的例子:长度i=10,有5组,每组和为20,是不符合条件的,因为找不到这个中间数(10才是中间数,但只有这一个)

另外,不需要遍历从2到S的数,因为序列长度到达某个位置,就算符合条件也不能找到足够数量的正整数了。如S=100,i=40,一共20组每组之和为5,但是5/2之前只有2个数了!

时间复杂度
O(n*sqrt(n)

代码

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
        for(int i=(int)Math.sqrt(sum*2);i>1;i--){
           if( i % 2==1 && sum%i == 0 ){//长度是奇数,并且sum/i为整数,说明存在存在
               ArrayList<Integer> list = new ArrayList<Integer>();
               int k = sum/i;
               for(int j=k-i/2;j<=k+i/2;j++)
                   list.add(j);
               lists.add(list);
           }
           if( i % 2==0 && sum%(i/2) ==0 && (sum/(i/2))%2 ==1 ){
               //长度是偶数,有i/2组,sum/组数 是奇数,说明存在
               ArrayList<Integer> list = new ArrayList<Integer>();
               int k = sum/i;
               for(int j=k-i/2+1; j<=k+i/2; j++)
                   list.add(j);
               lists.add(list);
           }
       }
        return lists;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值