题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
算法分析
假设序列的起始值为small,序列的结束值为big。那么存在一个中间值middle = (sum + 1) / 2使得small < middle一定成立。如果当前序列的和比sum小的时候,那么就依次增加big(big ++ ),使之趋近于sum。如果当前值比sum大,那么就依次减掉small,也使之趋近于sum。这样一直循环就可以找到所有的序列。
算法实现
import java.util.ArrayList;
public class Solution {
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 middle = (sum + 1) / 2;
int curSum = small + big;
// 当最小值不超过中间值的时候,一直查找
while(small < middle){
// 如果当前的和就是,保存当前序列
if(curSum == sum){
result.add(getSequeuence(small,big));
}
// 如果当前值比sum大,依次减掉较小的值
while(curSum > sum && small < middle){
curSum -= small;
small ++;
if(curSum == sum){
result.add(getSequeuence(small,big));
}
}
// 正常情况下,增加较大的值
big ++;
curSum += big;
}
return result;
}
/**
* 根据最小值与最大值,返回连续的数字序列
*/
private ArrayList<Integer> getSequeuence(int small,int big){
ArrayList<Integer> arr = new ArrayList();
for(int i=small; i<=big; i++){
arr.add(i);
}
return arr;
}
}