题目描述
找出所有和为S的连续正数序列,序列内按照从小到大顺序,序列间按照开始数字从小到大
有三种思路:
1. 暴力求解
2. 连续整数序列 是公差为1的等差数列 和为S 长度为N 的中间值为S/N
N为奇数时,中间值正好是平均值 条件为 i % 2 == 1 && sum % i == 0
N为偶数时,中间两个数的平均值是序列的平均值 条件为 i % 2 == 0 && (sum % i) * 2 == i
3. 滑动窗口的思想
代码如下:
class Solution {
public:
//方法一:暴力求解
vector<vector<int> > find_sequence_common(int sum){
vector<vector<int> > result;
for(int i = 1; i < sum; i++){
int index = i;
int tmpsum = sum;
vector<int> sequence;
while(tmpsum > 0){
sequence.push_back(index);
tmpsum -= index++;
}
if(0 == tmpsum){
result.push_back(sequence);
}
}
return result;
}
//方法二:求平均值 连续整数序列 是公差为1的等差数列 和为S 长度为N 的中间值为S/N
// N为奇数时,中间值正好是平均值 条件为 i % 2 == 1 && sum % i == 0
// N为偶数时,中间两个数的平均值是序列的平均值 条件为 i % 2 == 0 && (sum % i) * 2 == i
vector<vector<int> > find_sequence_average(int sum){
vector<vector<int> > result;
for(int i = sqrt(sum*2); i >= 2 ; i--){
if((i % 2 == 1 && sum % i == 0) ||
(i % 2 == 0 && (sum % i) * 2 == i)){
cout << i << endl;
vector<int> sequence;
for(int k = 0, j = sum / i - (i-1)/2; j > 0 && k < i; k++, j++){
sequence.push_back(j);
}
result.push_back(sequence);
}
}
return result;
}
//方法三:滑动窗口的思想 设两个指针
// 当和小于sum时 right++
// 当和大于sum时 left++
vector<vector<int> > find_sequence_slide_window(int sum){
vector<vector<int> > result;
int left = 1;
int right = 2;
while(right > left){
int temp = (left + right) * (right - left + 1) / 2;
if(temp < sum){
right++;
}
else if(temp > sum){
left++;
}
else{
vector<int> sequence;
for(int i = left; i <= right; i++){
sequence.push_back(i);
}
result.push_back(sequence);
left++;
}
}
return result;
}
vector<vector<int> > FindContinuousSequence(int sum) {
//return find_sequence_common(sum);
//return find_sequence_slide_window(sum);
return find_sequence_average(sum);
}
};