解法一:暴力破解
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值。
- curr<sum: r++;
- curr>sum: l++;
- 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; } }