NO41、和为S的连续整数序列(好题,再刷)

这篇博客介绍了两种方法找到所有和为S的连续正数序列,包括滑动窗口优化的解法和暴力求解策略。讨论了C++实现的细节,并分享了在牛客和力扣上的执行效率。文章最后邀请读者互动并提供了笔记PDF获取方式。
41、和为S的连续整数序列 再刷

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

9

返回值

[[2,3,4],[4,5]]

输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
1、牛客解法,很厉害。类似于TCP滑动窗口
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> result;
        int low=1,high=2;//两个起点,相当于动态窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小
        while(low<high){
            int sumTemp = (low+high) *(high-low +1)/2;
             //由于是连续的,差为1的一个序列,那么求和公式是(a0+an)*n/2
            if(sumTemp == sum){  //相等,那么就将窗口范围的所有数添加进结果集
                vector<int> resultTemp;
                for(int i=low;i<=high;++i)
                {resultTemp.push_back(i);}
                result.push_back(resultTemp);
                low++;
            }else if(sumTemp<sum){ //如果当前窗口内的值之和小于sum,那么右边窗口右移一下
                high++;
            }
            else{  //如果当前窗口内的值之和大于sum,那么左边窗口右移一下
                low++;
            }
        }
        return result;
    }
2、暴力解法
    vector<vector<int> > FindContinuousSequence(int sum) {
	vector<vector<int> > result;
	for (int n = sqrt(2 * sum); n >= 2; --n) {
		if (((n & 1) == 1 && sum % n == 0) || (sum % n * 2 == n)) {
			vector<int> res;
			//j用于计数,k用于遍历求值
			for (int j = 0, k = sum / n - (n - 1) / 2; j < n; j++, k++)//注意看k的求法
				res.push_back(k);
			result.push_back(res);
		}
	}
	return result;
    }

二刷:
1、滑动窗口,直接用数学公式来进行计算

运行时间:3ms 占用内存:496k

    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> result;
        int low = 1,high = 2;
        while(low < high){
           int sumTemp = (low + high) * (high - low + 1)/2;
           if(sumTemp == sum){
               vector<int> temp;
               for(int i = low;i <= high; ++i)
                   temp.push_back(i);
               result.push_back(std::move(temp));
               low++;//即使当前满足,那么依然要前进的,这有点滑动窗口的意思吧
           }else if(sumTemp < sum) high++;
            else
                low++;
        }
        return std::move(result);//借助C++11的move函数,总体时间会更短    
    }

力扣做法

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:6.9 MB, 在所有 C++ 提交中击败了39.52%的用户

    vector<vector<int>> findContinuousSequence(int target) {

        vector<vector<int>> result;
        int low = 1,high = 2;
        while(low < high){
           int sumTemp = (low + high) * (high - low + 1)/2;
           if(sumTemp == target){
               vector<int> temp;
               for(int i = low;i <= high; ++i)
                   temp.push_back(i);
               result.push_back(std::move(temp));
               low++;
           }else if(sumTemp < target) high++;
            else
                low++;
        }
        return std::move(result);//借助C++11的move函数,总体时间会更短    
    }

美女帅哥们如果觉得写的还行,有点用的话麻烦点个赞或者留个言支持一下阿秀~
如果觉得狗屁不通,直接留言开喷就完事了。

需要该笔记PDF版本的去个人公众号【拓跋阿秀】下回复“阿秀剑指offer笔记”即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拓跋阿秀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值