输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列
解题思路
用一个滑动窗口, 两个指针i, j
一左一右
计算两个指针范围内所有数之和
计算和:
- 一开始先
i = 1, j = 2, sum = 1 + 2
- 判断sum与target的关系
- 如果等于, 则将序列添加到结果集, 并且
sum += ++j
(这里注意是++j
, 因为下一轮窗口往右拓展, 需要加上j + 1) - 如果小于, 则也是窗口往右拓展
sum += ++j
- 如果大于, 则窗口左边需要往右移动,
sum -= i++
(注意这里是i++
, 因为需要减掉i
然后再往右移动)
- 如果等于, 则将序列添加到结果集, 并且
- 优化点: 避免重复计算, 不采用等差数列求和公式, 而是直接利用上一次的计算结果进行加减
代码
class Solution {
public int[][] findContinuousSequence(int target) {
LinkedList<int[]> result = new LinkedList<>();
int sum = 1 + 2;
for (int i = 1, j = 2; i < j; ) {
if (sum == target) {
int[] seq = new int[j - i + 1];
for (int k = 0; k < seq.length; k++) {
seq[k] = i + k;
}
result.add(seq);
sum += ++j;
} else if (sum < target) {
sum += ++j;
} else {
sum -= i++;
}
}
return result.toArray(new int[0][]);
}
}