和为S的连续正数序列

Posted by DH on July 19, 2017

题目

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

输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

分析

设置两个指针,如果指针之间连续的数的和<S,就把后一个指针向后移动。

如果移动之后,和>S,就把第一个指针后移。

过程如下图所示:

注意第二个指针指向的数不能大于sum,带个指针指向的数不能大于(sum+1)/2

代码

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
       	
       ArrayList <ArrayList<Integer>> resultList  = new ArrayList<>();
       
        // 如果要求的和小于2,找不到满足条件的
        if(sum <= 2){
            return resultList;
        }
        
        // 第一个指针指向1
        int first = 1;
        // 第二个指针指向2
        int last = 2;
        
        // 第一个数不能超过sum的一半
        int maxFirst = (sum + 1)/2;
        
        // 记录当前的和
        int tempSum = 0;
        
        while(first < last && first < maxFirst && last < sum){
            // 计算当前的和
            tempSum = (last + first) * (last - first + 1)/2;
            
            // 如果正好是sum,就将这个区间的数加入到list,并将这个list 加入到结果list
            if(tempSum == sum){
                
            	ArrayList <Integer> result = new ArrayList<>();
            	for(int i = first;i<=last;i++){
                	result.add(i);
            	}
            
            	resultList.add(result);
                //lsst后移
                last++;
            }else if(tempSum < sum){// 小于sum,第二个指针后移
                last++;
            
            }else{// 大于sum,第一个数后移
                first++;
            }
        }
       return resultList;
    }
}