package project;
import java.util.ArrayList;
/**
* 题目:和为S的连续正数序列。求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。
* 没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。你能不能也很快的找出所有和为S的连续正数序列?
* 思路:采用滑动窗口的思想,分为两步: 1)设定两个指针,左指针指向第一个数,右指针指向第二个数;
* 2)判断两个指针之间所有数的和与目标和的大小关系,滑动两个指针: 如果两个指针之间所有数的和等于目标和,则把这些数都添加到一个序列中;
* 如果大于目标和,则说明范围太大,因此减小范围,左指针向后移动一位; 如果小于目标和,则说明范围太小,因此增大范围,右指针向后移动一位。
*
* @author hexiaoli
*/
public class Main {
public static ArrayList<ArrayList<Integer>> findContinuousSequence(int sum) {
// 存储结果
ArrayList<ArrayList<Integer>> listAll = new ArrayList<>();
// 设置头尾指针
int head = 1;
int tail = 2;
while (head < tail) {
// 当前两个指针范围内的数字和等于目标和,添加至list
int currentSum = (head + tail) * (tail - head + 1) / 2;
if (currentSum == sum) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = head; i <= tail; i++) {
list.add(i);
}
listAll.add(list);
// 首指针向后移动
head++;
} else if (currentSum > sum) {// 当前两个指针范围内的数字和大于目标和,左边指针向后移动,减小范围
head++;
} else {// 当前两个指针范围内的数字和小于目标和,右边指针向后移动,增大范围
tail++;
}
}
return listAll;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> listAll = findContinuousSequence(15);
for (ArrayList<Integer> it1 : listAll) {
for (Integer it2 : it1) {
System.out.print(it2 + " ");
}
System.out.println();
}
}
}