面试题57 - II. 和为s的连续正数序列
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
解法一:前缀和+二分
首先求前缀和,枚举每一个前缀和sum[i],在0~i 之间二分另外一个前缀和sum[mid],使得sum[i] - sum[mid] == target。
class Solution {
public:
long long sum[100000+50];
vector<vector<int>> findContinuousSequence(int target) {
for(int i=1; i<=(target+1)/2; i++) {
sum[i] = sum[i-1]+i;
}
vector<vector<int> > ret;
for(int i=1; i<=(target+1)/2; i++) {
if(sum[i]+sum[i-1] < target)
continue;
int left = 0, right = i-1;
while(left <= right) {
int mid = (left+right)/2;
if(sum[i] - sum[mid]==target) {
vector<int> tmp;
for(int j=mid+1; j<=i; j++) {
tmp.push_back(j);
}
ret.push_back(tmp);
break;
}
else if(sum[i]-sum[mid]> target)
left = mid+1;
else right = mid-1;
}
}
return ret;
}
};
解法二:滑动窗口
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>>vec;
vector<int> res;
for (int l = 1, r = 2; l < r;){
int sum = (l + r) * (r - l + 1) / 2;
if (sum == target){
res.clear();
for (int i = l; i <= r; ++i) res.push_back(i);
vec.push_back(res);
l++;
}
else if (sum < target) r++;
else l++;
}
return vec;
}
};