title: 每日一練(30):和為s的連續正數序列
categories:[劍指offer]
tags:[每日一練]
date: 2022/03/04
每日一練(30):和為s的連續正數序列
輸入一個正整數 target ,輸出所有和為 target 的連續正整數序列(至少含有兩個數)。
序列內的數字由小到大排列,不同序列按照首個數字從小到大排列。
示例 1:
輸入:target = 9
輸出:[[2,3,4],[4,5]]
示例 2:
輸入:target = 15
輸出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
方法一:暴力求和公式
vector<vector<int>> findContinuousSequence(int target) {
if (target < 3) {
return {};
}
int left = 1;
double right = 2.0;
vector<vector<int>> res;
while (left < right) {
right = (-1 + sqrt(1 + 4 * (2 * target + (long)left * left - left))) / 2;
if (left < right && right == (int) right) {
vector<int> ans;
for (int i = left; i <= (int)right; i++) {
ans.push_back(i);
}
res.push_back(ans);
}
left++;
}
return res;
}
方法二:滑動視窗
演算法流程:
1.初始化: 左邊界 left = ,右邊界 right = 2 ,元素和 sum = 3 ,結果列表 res ;
2.迴圈: 當 left >= right 時跳出;
- 當 sum > targets時: 向右移動左邊界 left = left + 1 ,並更新元素和 sum ;
- 當 sum < targets 時: 向右移動右邊界 right = right + 1 ,並更新元素和 sum ;
- 當 sum = targets 時: 記錄連續整數序列,並向右移動左邊界 left = left + 1 ;
3.返回值: 返回結果列表 res ;
vector<vector<int>> findContinuousSequence(int target) {
if (target < 3) {
return {};
}
int left = 1, right = 2, sum = 3;
vector<vector<int>> res;
while (left < right) {
if (sum == target) {
vector<int> vec;
for (int i = left; i <= right; i++) {
vec.push_back(i);
}
res.push_back(vec);
}
if (sum >= target) {
sum -= left;
left++;
} else {
right++;
sum += right;
}
}
return res;
}