题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
解题思路
1.和为S,则这个序列中可能存在的最大的数应该为(S+1)/2(考虑奇数),所以从1开始遍历到(S+1)/2,中间一个while循环加入一个判断前面的序列和是否等于S。
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
int len = (sum+1)/2;
for(int i=1;i<len;i++)
{
int sum1 = 0;
int temp2 = i;
while(sum1<sum)
{
sum1 = sum1 + temp2;
temp2++;
}
if(sum1 == sum)
{
ArrayList<Integer> temp = new ArrayList<>();
for(int j = i; j<temp2;j++)
temp.add(j);
list.add(temp);
}
}
return list;
}
}
2.双指针思路:就是相当于有一个窗口,窗口的左右两边就是两个指针,我们根据窗口内值之和来确定窗口的位置和宽度。
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
int low = 1;
int high = 2;
while(high>low)
{
int sum1 = (high + low) * (high - low + 1) / 2; //等差数列求和
if(sum1==sum)
{
ArrayList<Integer> temp = new ArrayList<>();
for(int j = low; j<=high;j++)
temp.add(j);
list.add(temp);
low++;
}
else if(sum1>sum)
low++; //如果当前窗口内的值之和大于sum,那么左边窗口右移一下
else
high++; //如果当前窗口内的值之和小于sum,那么右边窗口右移一下
}
return list;
}