解法一:暴力破解

1.0 左右指针 三层循环 每次将中间圈定的所有值相加 判断
2.0 左右指针 两层循环 前缀和
3.0 左右指针 两层循环 公式法计算等差数列
具体代码略

解法二:中点法

名字是我自己取的。
依据如下:
如果存在一个符合要求的长度为n的连续正数序列,那么((double) sum)/n一定是该连续正数序列的中位数。

  • [10,11,12,13,14]长度为5,和为60。60/5=12正好是它的中位数。
  • [24,25,26,27]长度为4,和为102。102/4=25.5正好是它的中位数。

(实际上就是平均数,只是在等差数列中中位数和平均数相等。)
以此为依据,我们可以从中位数向两端延伸,得到这个数组。

  • 如果序列长度n为奇数,那么 ((double) sum)/n必须是整数,并且数组左边界要>0。
  • 如果序列长度n为奇数,那么 ((double) sum)/n应该是整数+0.5,所以((double) sum)/n一定不是整数,但((double) 2*sum)/n必须是整数,并且数组左边界要>0。

满足以上条件的数组就可以存起来了。

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();
        for(int i=sum; i>=2; i--){
            if(i%2==1&&sum%i==0&&sum/i-i/2>0){
                ArrayList<Integer> l=new ArrayList<>();
                for(int j=sum/i-i/2; j<=sum/i+i/2; j++)
                    l.add(j);
                list.add(l);
            }else if(i%2==0&&sum%i!=0&&(sum*2)%i==0&&sum/i-i/2+1>0){
                ArrayList<Integer> l=new ArrayList<>();
                for(int j=sum/i-i/2+1; j<=sum/i+i/2; j++)
                    l.add(j);
                list.add(l);                
            }
        }
        return list;
    }
}

解法三:数学公式法

其实思想和解法二是有些类似的,都是以划分份数为指示变量进行循环的。
非原创,思路参考 @若星汉天空https://www.nowcoder.com/questionTerminal/c451a3fd84b64cb19485dad758a55ebe?answerType=1&f=discussion
respect!

消去 ,我们发现如果给定,就能直接求出

显然只有为整数时才有意义,因此这就是我们的判断条件。

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> ans=new ArrayList<>();
        for(int n=sum; n>=2; n--){
            double x0=((double)2*sum+n-n*n)/n/2;
            if((int) x0!=x0||x0<1) continue;
            ArrayList<Integer> list=new ArrayList<>();
            int k=(int) x0;
            while(list.size()<n) list.add(k++);
            ans.add(list);
        }
        return ans;
    }
}

解法四:滑动窗口法

左右指针都只会右移。分以下三种情况,每一次滑动时记得要更新curr值。

  1. curr<sum: r++;
  2. curr>sum: l++;
  3. curr==sum: 记录;l++;r++;
    import java.util.*;
    public class Solution {
     public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
         ArrayList<ArrayList<Integer>> ans=new ArrayList<>();
         int l=1, r=1, curr=1;
         while(l*2<sum&&r<sum){
             if(curr<sum) {
                 curr+=r+1; r++;
             }else if(curr>sum) {
                 curr-=l; l++;
             }
             else{
                 ArrayList<Integer> list=new ArrayList<>();
                 int k=l;
                 while(k<=r) list.add(k++);
                 ans.add(list);
                 curr=curr+r+1-l;
                 l++; r++;
             }
         }
         return ans;
     }
    }