# 剑指Offer题解 - Day54
# 剑指 Offer 57 - II. 和为 s 的连续正数序列
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
1
2
2
限制:
1 <= target <= 10^5
思路:
本题可以采用双指针求解。按照题目描述,需要找出所有和为目标值的 连续正整数 序列。那么此时声明两个指针,左指针指向 1 ,右指针指向 2 。同时初始化包括左右指针在内所有连续正整数之和的变量s,默认为 3 。指针区间就是一个滑动窗口。
然后判断s和目标值的关系,如果相等,则将滑动窗口内的数字整合成数组,并添加到结果数组中。
s ≥ target
的时候需要将滑动窗口缩小,也就是将左侧的值从s中减去,并右移左指针。
s < target
的时候需要将滑动窗口扩大,也就是将右指针右移,并将右侧的值添加到s中。
# 双指针
/**
* @param {number} target
* @return {number[][]}
*/
var findContinuousSequence = function(target) {
let i = 1; // 初始化变量
let j = 2;
let s = 3;
let res = []; // 初始化结果数组
while(i < j) {
if (s === target) {
res.push(Array.from({ length: j - i + 1 }).map((_, index) => index + i))
}
if (s < target) {
j++;
s += j;
} else {
s -= i;
i++;
}
}
return res;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- 时间复杂度 O(n)。
- 空间复杂度 O(1)。
分析:
当s === target
时,我们需要将滑动窗口内的元素生成一个数组,并添加到结果数组中。生成的方是通过map
遍历,将每个元素的值设置为 index + i
,从而得到递增的正整数数组。
还需要注意的是,缩小滑动窗口时,需要先将当前左指针所在的数字从s中减去,再右移左指针。如果先右移左指针的话,就会多减去 1 ,导致最终结果异常。同样的,扩大滑动窗口的时候,需要先右移右指针,再将当前右指针所在的数字添加到s中。如果先添加右指针元素的话,就会导致右指针元素重复添加一次,从而少添加1,导致最终结果异常。
# 总结
本题考查双指针。同时需要注意修改s和指针移动的顺序。如果顺序写反,得到的结果就是错误的。