(剑指Offer)面试题41:和为s的连续正数序列

题目:

输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1-5,,4-6和7-8.

思路:

题目求的是连续正数序列,而且至少含有两个数,那么我们可以从1,2这两个数开始,

以求和为9的所有连续序列为例,假设两个指针pSmall和pBig,分别指向正数序列的首尾,pSum表示序列之和,一开始pSmall=1,pBig=2,,pSum=3<9,序列需要包含更多的数,于是pBig+1,此时pSum=6,依旧小于9,于是pBig+1,此时pSum=10,大于9,序列需要删除一些数,于是pSmall-1,pSum=9,找到第一个满足条件的序列;接着pBig+1,按照前面的方法继续查找满足条件的序列,直到pSmall等于(s+1)/2.

代码:

#include <iostream>
#include <vector>
using namespace std;

void PrintContinuousSequence(int pSmall,int pBig){
    for(int i=pSmall;i<=pBig;i++)
        cout<<i<<" ";
    cout<<endl;
}

void FindContinuousSequence(int sum){
    if(sum<3)
        return;

    int pSmall=1;
    int pBig=2;
    int halfSum=((sum+1)>>1);
    int curSum=pSmall+pBig;

    while(pSmall<halfSum){
        if(curSum==sum)
            PrintContinuousSequence(pSmall,pBig);

        while(curSum>sum && pSmall<pBig-1){
            curSum-=pSmall;
            pSmall++;
            if(curSum==sum)
                PrintContinuousSequence(pSmall,pBig);
        }

        pBig++;
        curSum+=pBig;
    }
}

int main()
{
    FindContinuousSequence(3);

    return 0;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/c451a3fd84b64cb19485dad758a55ebe?rp=2

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck! 

输出描述:输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

AC代码:

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > result;
        if(sum<3)
            return result;

        int pSmall=1;
        int pBig=2;
        int curSum=pSmall+pBig;
        int halfSum=((sum+1)>>1);
        vector<int> sequence;

        while(pSmall<halfSum){
            if(curSum==sum){
                GetSequence(pSmall,pBig,sequence);
                result.push_back(sequence);
            }
            
			// at least two numbers
            while(curSum>sum && pSmall<pBig-1){
                curSum-=pSmall;
                pSmall++;

                if(curSum==sum){
                    GetSequence(pSmall,pBig,sequence);
                    result.push_back(sequence);
                    break;
                }
            }

            pBig++;
            curSum+=pBig;
        }

        return result;
    }

    void GetSequence(int pSmall,int pBig,vector<int> &sequence){
        sequence.clear();
        for(int i=pSmall;i<=pBig;i++)
  			sequence.push_back(i);
    }
};

 

posted @ 2015-07-28 12:57  AndyJee  阅读(1512)  评论(0编辑  收藏  举报