剑指Offer: 和为S的连续正数序列

剑指Offer: 和为S的连续正数序列

题目描述

输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。

样例
输入:15

输出:[[1,2,3,4,5],[4,5,6],[7,8]]

算法 双指针

设置两个指针 ij ,分别指向连续正数序列的起始和终止
用Sn表示当前连续正数序列的和
j 递增的方式遍历整个序列(1到n), 这里可以优化下只需要遍历中间节点的下一个就可以了。 代表查找以 i开头 的时候 结尾j 应该是多少。当Sn < sum说明 j 应该往后移动,当 Sn=sum 说明满足题意,当 Sn > sum 说明向后走即可。

时空分析

时间复杂度: O(n)

C++ 代码
class Solution {
public:
    vector<vector<int> > findContinuousSequence(int sum) {
        vector<vector<int> > res;
        vector<int> path;
        int Sn = 0;
        for(int i=1, j=2; j <= sum/2+1; ) {
            Sn = (i + j)*(j - i + 1)/2;
            if (Sn == sum) {
                int k = i;
                while(k <= j) {
                    path.push_back(k);
                    k++;
                }
                res.push_back(path);
                path.clear();
                i++;
                j++;
            }
            else if (Sn > sum)
                i++;
            else if (Sn < sum)
                j++;
        }
        return res;
    }
};

第一版写的程序:

class Solution {
public:
    vector<vector<int> > findContinuousSequence(int sum) {
        vector<vector<int> > res;
        vector<int> cres;
        if (sum < 3)
            return res;
        int i = 1, j = 1;
        int Sn = 0;
        while(i <= sum/2+1)
        {
            Sn += i;
            while (Sn > sum)
            {
                Sn -= j;
                j++;
            }
            
            if (Sn == sum)
            {
                cres.clear();
                for(int index = j; index <= i; index++)
                    cres.push_back(index);
                res.push_back(cres);
            }
                
            i++;
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Erice_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值