小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

本文探讨了两种高效算法,用于找出所有可能的连续正数序列,这些序列的元素和等于给定的整数S。第一种算法通过数学公式确定序列长度和中间值,第二种算法采用双指针技术进行动态调整,实现简洁且直观。文章详细解释了每种算法的逻辑,并提供了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
思路1:

1)由于我们要找的是和为S的连续正数序列,因此这个序列是个公差为1的等差数列,而这个序列的中间值代表了平均值的大小。
假设序列长度为n,那么这个序列的中间值可以通过(S / n)得到,知道序列的中间值和长度,也就不难求出这段序列了。

2)满足条件的n分两种情况:
n为奇数时,序列中间的数正好是序列的平均值,所以条件为:(n & 1) == 1 && sum % n == 0;
n为偶数时,序列中间两个数的平均值是序列的平均值,而这个平均值的小数部分为0.5,所以条件为:(sum % n) * 2 == n.

3)体面要求序列间按照开始数字从小到大的顺序,而n越大开始数字自然越小,所以从最大n依次递减。假定从1开始加求得超过
100对应的n值,由等差数列公示S=(1+n)*n/2,n=sqrt(2*s)
*/

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > res;
        for(int n=sqrt(2*sum);n>=2;n--){
            if(((n&1)==1 && sum%n==0) || (sum%n)*2==n){
                vector<int> temp;
                for(int i=0;i<n;i++){
                    temp.push_back((sum / n) - (n - 1) / 2 + i);
                }
                res.push_back(temp);
            }
        }
        return res;
    }
};

/*
思路2:
双指针问题
利用高低两个指针,当前总和小于sum时大指针++;
总和小于sum时小指正++;直到相等时输出数组,大指针++。
该方案思路明确,需要一些无用的循环,比思路1的空间复杂度要高。
*/

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > res;
        int pl = 1,ph = 2;
        while(pl<ph){
            int curSum = (pl + ph) * (ph - pl + 1) / 2;
            if(curSum < sum)
                ph++;
            if(curSum == sum){
                vector<int> temp;
                for(int i=pl;i<=ph;i++){
                    temp.push_back(i);
                }
                res.push_back(temp);
                ph++;
            }
            if(curSum > sum)
                pl++;
        }
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值