小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? 
   数据范围:
进阶:时间复杂度)
 
                                        进阶:时间复杂度
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
9
[[2,3,4],[4,5]]
0
[]
//左神的思路,双指针问题
//当总和小于sum,大指针继续+
//否则小指针+
class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > allRes;
        int phigh = 2,plow = 1;
        
        while(phigh > plow){
            int cur = (phigh + plow) * (phigh - plow + 1) / 2;
            if( cur < sum)
                phigh++;
            
            if( cur == sum){
                vector<int> res;
                for(int i = plow; i<=phigh; i++)
                    res.push_back(i);
                allRes.push_back(res);
                plow++;
            }
            
            if(cur > sum)
                plow++;
        }
        
        return allRes;
    }
};
import java.util.ArrayList;
/*
*初始化small=1,big=2;
*small到big序列和小于sum,big++;大于sum,small++;
*当small增加到(1+sum)/2是停止
*/
public class Solution {
    public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
    	ArrayList<ArrayList<Integer>> lists=new ArrayList<ArrayList<Integer>>();
        if(sum<=1){return lists;}
        int small=1;
        int big=2;
        while(small!=(1+sum)/2){          //当small==(1+sum)/2的时候停止
            int curSum=sumOfList(small,big);
            if(curSum==sum){
                ArrayList<Integer> list=new ArrayList<Integer>();
                for(int i=small;i<=big;i++){
                    list.add(i);
                }
                lists.add(list);
                small++;big++;
            }else if(curSum<sum){
                big++;
            }else{
                small++;
            }
        }
        return lists;
    }
    
    public int sumOfList(int head,int leap){        //计算当前序列的和
        int sum=head;
        for(int i=head+1;i<=leap;i++){
            sum+=i;
        }
        return sum;
    }
}
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        res=[]
        for i in range(1,tsum//2+1):
            sumRes=i
            for j in range(i+1,tsum//2+2):
                sumRes+=j
                if sumRes==tsum:
                    res.append(list(range(i,j+1)))
                    break
                elif sumRes>tsum:
                    break
        return res
                                                                                    /* 用两个数字begin和end分别表示序列的最大值和最小值, 首先将begin初始化为1,end初始化为2. 如果从begin到end的和大于s,我们就从序列中去掉较小的值(即增大begin), 相反,只需要增大end。 终止条件为:一直增加begin到(1+sum)/2并且end小于sum为止 */class Solution { public: vector<vector<int> > FindContinuousSequence(int sum) { vector<vector<int> > res; if(sum < 3) return res; int mid = (sum + 1)>>1; int begin = 1; int end = 2; int cur = begin + end; while(begin < mid && end < sum) { while(cur > sum) { cur -= begin; begin++; } if(cur == sum) InsertRes(begin,end,res); end++; cur += end; } return res; } void InsertRes(int begin,int end,vector<vector<int> > &res) { vector<int> temp; for(int i = begin;i<=end;i++) temp.push_back(i); res.push_back(temp); } };
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        if tsum < 3:
            return []
        
        res = []
        small = 1
        big = 2
       	mid = (1 + tsum) / 2
        curSum = small + big
        
        while small < mid:
            if curSum == tsum:
                res.append(range(small, big + 1))
                small += 2
                big += 1
                curSum -= small * 2 - 3
                curSum += big
            elif curSum < tsum:
                big += 1
                curSum += big
            else:
                curSum -= small
                small += 1
        
        return res
            
public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
		ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
		if (sum < 3)
			return listAll;
		int small = 1;
		int big = 2;
		int middle = (sum + 1) / 2;
		int curSum = 3;
		while (small < middle) {
			while (curSum < sum) {
				big++;
				curSum += big;
			}
			if (curSum == sum) {
				ArrayList<Integer> list = new ArrayList<>();
				for (int i = small; i <= big; i++) {
					list.add(i);
				}
				listAll.add(list);
			}
			curSum -= small;
			small++;
		}
		return listAll;
	}
typedef vector<int> vi;
typedef vector<vi> vvi;
class Solution {
public:
    vvi FindContinuousSequence(int sum) {
        vvi res;
        sum <<= 1;
        for(int i = 2; i * i <= sum; ++i) if(sum % i == 0){
            int j = sum / i, t = (j - i + 1);
            if(!(t & 1)){
                res.push_back(vi());
                vi& v = res[res.size() - 1];
                t >>= 1;
                for(int a = t; a <= j - t; ++a) v.push_back(a);
            }
        }
        for(int i = 0, j = int(res.size()) - 1; i < j; ++i, --j) swap(res[i], res[j]);
        return res;
    }
};
  //我竟然解了二元一次方程,我是菜鸟我怕谁。。
//(start+end)*(end-start+1)/2=sum; 
//根据start解出end。。。。。
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
         ArrayList<ArrayList<Integer>> result=new ArrayList<ArrayList<Integer>>();
        if(sum<3) return result;
        for(int i=1;i<=sum/2;i++){
            int value=1+4*i*i-4*i+8*sum;
            int valueSqrt=(int)Math.sqrt(value);
            if(value>=25&&valueSqrt*valueSqrt==value){
                ArrayList<Integer> path=new ArrayList<Integer>();
                for(int j=i;j<=(valueSqrt-1)>>1;j++)
                    path.add(j);
                result.add(path);
            }
        }
        return result;
    }
# Python 感觉比较简短的代码了
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        l, r, sum, res = 1, 2, 3, []
        while l<r:
            if sum>tsum:
                sum -= l
                l += 1
            else:
                if sum==tsum:
                    res.append([i for i in range(l,r+1)])
                r += 1
                sum += r
        return res 等差数列求和直接公式算
class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<int> tmp;
        vector<vector<int> > ans;
        for(int i = 1; i < sum; i++){
            double b = (sqrt(4*i*i-4*i+8*sum+1) - 1.0)/2.0;
            int b_int = floor(b + 0.5);
            if(abs(b - b_int) < 1e-3){
                for(int j = i; j <= b_int; j++) tmp.push_back(j);
                ans.push_back(tmp);
                tmp.clear();
            }
        }
        return ans;
    }
};
                                                                                    def FindContinuousSequence(self, tsum): if tsum < 3: return [] res, arr = [], [1, 2] middle = tsum // 2 + 1 while arr and arr[0] < middle: if sum(arr) < tsum: arr.append(arr[-1] + 1) elif sum(arr) > tsum: arr.pop(0) else: res.append([i for i in arr]) arr.append(arr[-1] + 1) arr.pop(0) if not arr: return [] return res
import java.util.ArrayList;
/**
 * 题目描述
 * 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。
 * 但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。
 * 没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。
 * 现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
 * 输出描述:
 * 输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
 *
 * @author shijiacheng
 */
public class FindContinuousSequenceSolution {
    public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if (sum < 3){
            return result;
        }
        int small = 1;
        int big = 2;
        int curSum = small +big;
        int middle = (sum+1)/2;
        while (small<middle){
            if (curSum == sum){
                ArrayList<Integer> temp = new ArrayList<>();
                for (int i = small; i <= big; i++) {
                    temp.add(i);
                }
                result.add(temp);
            }
            while (curSum > sum && small<middle){
                curSum -= small;
                small++;
                if (curSum == sum){
                    ArrayList<Integer> temp = new ArrayList<>();
                    for (int i = small; i <= big; i++) {
                        temp.add(i);
                    }
                    result.add(temp);
                }
            }
            big++;
            curSum += big;
        }
        return result;
    }
}
                                                                                    class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;
        if(sum<3)
            return res;
		int begin = 1;
        int end = 2;
        //初始化curSum时直接用3,不要用a+b,这样效率会高一点
        int curSum = 3;
        int mid = (1+sum)>>1;
        //当begin<mid或者end<(mid+1)时,连续序列的和肯定超出sum了,所以这两个都要限制一下
        while(begin<mid && end<mid+1){
            while(curSum>sum){
                curSum -= begin;
                ++begin;
            }
            //这段代码不要上一个while之前,不然会代码重复,而且多了一次判断,效率不高
            if(curSum==sum)
                insertRes(begin,end,res);
            ++end;
            curSum += end;
        }
        return res;
    }
private:
    void insertRes(int a,int b,vector<vector<int>> &res){  vector<int> temp;
        for(int i=a;i<=b;++i)
            temp.push_back(i);
        res.push_back(temp);  }
};
import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer> > alal = new ArrayList<ArrayList<Integer> >();
        for(int i = 1; i <= sum/2; i++){
            ArrayList<Integer> al = new ArrayList<>();
            int tempSum = i;
            int nextNum = i;
            al.add(i);
            while(tempSum < sum){
                 nextNum++;
                 al.add(nextNum);
                if((tempSum += nextNum) == sum){
                    alal.add(al);
                    break;
                }
               
            }
        }
        return alal;
    }
}
import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
        for (int n = (int) Math.sqrt(2 * sum); n >= 2; n--) {
            if ((n & 1) == 1 && sum % n == 0 || (sum % n) * 2 == n) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int j = 0, k = (sum / n) - (n - 1) / 2; j < n; j++, k++) {
                    list.add(k);
                }
                ans.add(list);
            }
        }
        return ans;
    }
} /*
直接用数学方法做的
等差数列公式  2*n*a1+n(n-1)/2 = s; 由n>= 2 得 a1 <= (s - 1)/2
对首位数字a1从1到 (s - 1)/2遍历
等差数列公式变形   n*n+(2*a1 - 1)n-2s = 0
可得                        n = [-(2a - 1) + sqrt((2a - 1) * (2a - 1) + 8s)]/2
检验n是否为整数,是则得到一个答案
*/
vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > ans;
		int maxA1 = (sum - 1) / 2; //sum = n*a1 + n(n-1)/2 n最小为2 推导得到
		for(int i = 1; i <= maxA1; i++) //首位数字遍历
		{
			double f = (sqrt(double((2 * i - 1) * (2 * i - 1) + 8 * sum)) + 1 - 2 * i) / 2; //计算长度
			int n = int(f);
			if(abs(f - n) < 0.000001) //长度是整数,有效
			{
				vector<int> tempans;
				for(int j = 0; j < n; j++)
					tempans.push_back(i + j);
				ans.push_back(tempans);
			}
		}
		return ans;
    }
/*LinkedList.add复杂度低,所以用了LinkedList*/ public class Solution { public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) { ArrayList<ArrayList<Integer>> resultList = new ArrayList<ArrayList<Integer>>(); if(sum <= 2){ return resultList; } for(int start = 1;start <= (sum-1)/2; start++){ int end = start+1; int seqSum = (start+end)*(end-start+1)/2; LinkedList<Integer> result = new LinkedList<Integer>(); result.add(start); while(seqSum <= sum){ result.add(end); if(seqSum == sum){ resultList.add(new ArrayList<Integer>(result)); break; } end++; seqSum = (start+end)*(end-start+1)/2; } } return resultList; } }
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
    	ArrayList<ArrayList<Integer> > lists = new ArrayList<ArrayList<Integer> >();
        for(int k = 2; k*k < 2*sum; k++){
        	double m = ((2.0*sum)/k-k+1)/2.0;
        	int temp = (int)m;
        	if(m == temp){
        		ArrayList<Integer> list = new ArrayList<Integer>();
        		for(int i = 0; i < k; i++){
        			list.add(i+temp);
        		}
        		lists.add(0, list);
        	}
        }
        return lists;
    }  public ArrayList<ArrayList<Integer> > FindContinuousSequence_(int sum) {
    	ArrayList<ArrayList<Integer> > Lists = new ArrayList<ArrayList<Integer> >();
        for(int i = 2; i <= sum/2+1; i++){
        	if(i%2 == 1){
        		if(sum%i == 0){
        			int temp = sum/i;
        			if(temp-i/2 > 0){
        				ArrayList<Integer> tempList = new ArrayList<Integer>();
        				for(int j = temp-i/2; j <= temp+i/2; j++){
        					tempList.add(j);
        				}
        				Lists.add(0,tempList);
        			}
        		}
        	}else{
        		int temp = sum/i;
        		double temp1 = temp+0.5;
        		if((int)(temp1 * i) == sum){
        			if(temp-i/2+1 > 0){
        				ArrayList<Integer> tempList = new ArrayList<Integer>();
        				for(int j = temp-i/2+1; j <= temp+i/2; j++){
        					tempList.add(j);
        				}
        				Lists.add(0,tempList);
        			}
        		}
        	}
        }
        return Lists;
    } 
import java.util.ArrayList; public class Solution { public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) { //存放结果 ArrayList<ArrayList<Integer> > result = new ArrayList<>(); //两个起点,相当于动态窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小 int plow = 1,phigh = 2; while(phigh > plow){ //由于是连续的,差为1的一个序列,那么求和公式是(a0+an)*n/2 int cur = (phigh + plow) * (phigh - plow + 1) / 2; //相等,那么就将窗口范围的所有数添加进结果集 if(cur == sum){ ArrayList<Integer> list = new ArrayList<>(); for(int i=plow;i<=phigh;i++){ list.add(i); } result.add(list); plow++; //如果当前窗口内的值之和小于sum,那么右边窗口右移一下 }else if(cur < sum){ phigh++; }else{ //如果当前窗口内的值之和大于sum,那么左边窗口右移一下 plow++; } } return result; } }