41、剑指offer--和为S的连续正数序列
题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
解题思路:
1、定义start = 1,end =2 ,然后和res = start+end;如果res == sum,则表示找到一个序列,把start到end的值存入vector
2、如果大于的话,依次从小到大删除start,res减少,直到相等或者结束
3、如果小于的话,增大end,再次执行循环
循环结束条件start == (1+sum)/2
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 class Solution { 6 public: 7 vector<vector<int> > FindContinuousSequence(int sum) { 8 vector<vector<int> > result; 9 vector<int> tmp; 10 if(sum < 3) 11 return result; 12 int start = 1; 13 int end = 2; 14 int middle = (1+sum)/2; 15 //因为序列中至少需要有两个数字,因此start结束位置为(1+s)/2;例如和为9,start最大的为4 16 int res = start+end; 17 while(start < middle) 18 { 19 if(res == sum) 20 { 21 for(int i=start;i<=end;i++) 22 { 23 tmp.push_back(i); 24 } 25 result.push_back(tmp); 26 tmp.clear(); 27 } 28 //和大了,依次去掉小的值 29 while(res > sum && start < middle) 30 { 31 res -= start; 32 start++; 33 if(res == sum) 34 { 35 for(int i=start;i<=end;i++) 36 { 37 tmp.push_back(i); 38 } 39 result.push_back(tmp); 40 tmp.clear(); 41 } 42 } 43 //小了,big变大 44 end++; 45 res += end; 46 } 47 return result; 48 } 49 }; 50 int main() 51 { 52 int n; 53 while(cin>>n) 54 { 55 vector<vector<int> > v; 56 Solution s; 57 v = s.FindContinuousSequence(n); 58 int length = v[0].size(); 59 60 for(int i=0;i<v.size();i++) 61 { 62 for(int j=0;j<v[i].size();j++) 63 { 64 cout<<v[i][j]<<" "; 65 } 66 cout<<endl; 67 } 68 } 69 return 0; 70 }