剑指 Offer 57 - II. 和为s的连续正数序列
题目
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
思路
- 当窗口的和小于 target 的时候,窗口的和需要增加,所以要扩大窗口,窗口的右边界向右移动
- 当窗口的和大于 target 的时候,窗口的和需要减少,所以要缩小窗口,窗口的左边界向右移动
- 当窗口的和恰好等于 target 的时候,我们需要记录此时的结果。设此时的窗口为 [i, j)[i,j),那么我们已经找到了一个 ii 开头的序列,也是唯一一个 ii 开头的序列,接下来需要找 i+1i+1 开头的序列,所以窗口的左边界要向右移动
代码
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
int i = 1;// 滑动窗口的左边界
int j = 1; // 滑动窗口的右边界
int sum = 0; // 滑动窗口中数字的和
vector<vector<int>> res;// 存储若干滑动窗口的结果
while(i <= target / 2)
{
// 扩大滑动窗口
if(sum < target)
{
// 右边界向右移动
sum += j;
j++;
}
else if(sum > target)
{
// 缩小滑动窗口
sum -= i;
i++;
}
else{
// 记录结果
vector<int> arr;
// 将滑动窗口中的数字全部写入数组arr中 左闭右开区间
for(int k = i; k < j; k++)
{
arr.push_back(k);
}
res.push_back(arr);
// 写入之后 继续寻找下一组结果 滑动窗口向右移动 减去i即可
sum -= i;
i++;
}
}
return res;
}
};