解法:滑动窗口
思想:
维护一个左闭右闭的滑动窗口,左右边界只能增加,不能减小。根据和与target的关系来移动left与right,右移right是新增一个数,右移left是减去一个数。
复杂度:
●时间:O(N),遍历
●空间:O(1)
代码注意点(不看注释想出原因):
●while循环的条件为?
●left和right初值?
●left和right增和加/减的顺序
●找到一组答案后怎么继续遍历?
代码:
注意右移right是先增再加,右移left是先减再增
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>>res;
int left = 1, right = 0;
int sum = 0;
// 因为最少两个数,所以left > target / 2时,和肯定大于target
while(left <= target / 2){
if(sum < target){
// 因为需要左闭右闭,所以right先自增再+
right++;
sum += right;
}
else if(sum > target){
//左边就是先减再增
sum -= left;
left++;
}
else{
//记录结果,tmp为局部变量,自动析构
vector<int>tmp;
for(int i = left; i <= right; ++i){
tmp.push_back(i);
}
res.push_back(tmp);
//找到答案后需要继续往右,所以要去掉左边的一位
sum -= left;
left++;
}
}
return res;
}
};
改进:
刚好为和时,left可以去掉两位,因为去掉一位后,右边要加上一位,肯定大于target,所以左边还要去掉一位,可以一次性去掉两位。