【剑指Offer】和为s的连续正数序列 输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

题目重述

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

输出描述:

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

我的思路与代码:

可能最原始的思路,但是我做了优化之后感觉和剑指offer上思路的时间复杂度空间复杂度区别不大,复杂度高在了加起来不等于S 我依然用了循环和res.push_back。欢迎大家给与评论。

思路:

首先我们明白比如数字是100,那么连续序列肯定不会超过50= 100/2;又比如数字99那么连续相加序列也不会超过50= 99/2+1。这里我们为了不去区分奇偶数,都认为和为S的连续正数序列最多不超过 S/2+1,假设连续序列和是tmp;
tmp>sum 时给i++;
tmp<sum 时给j++

例如 S=5
[ 1 2 3 4 5]

相加等于5的连续序列的最大值不超过5/2+1=3;下来开始循环
当tmp<5时,res都会push_back i和j;当tmp>5时,res会清空;当tmp==5时,result.push_back(res),且对res清空处理并break。

i=1
tmp=i=1<5 那么 tmp=tmp+j=1+2=3<5 那么tmp=tmp+j=1+2+3=6>5 break;

i=2
tmp=2<5 那么 tmp=2+3=5 result.push_back(res),且对res清空处理并break;

i=3
tmp=i=3 但是j=i+1=4>(5/2+1) 因此退出循环,return result。

代码

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        int len = sum / 2 +1;
		vector<vector<int> > result;
		vector<int>res;
		if (sum <3) {
			return result;
		}
		else{
            for (int i = 1; i <= len; i++) {
                int tmp = i;
                res.push_back(i);
                for (int j = i+1; j <= len; j++) {
                    if(tmp<sum){
                        tmp += j;
                        res.push_back(j);
                    }
                    if (tmp > sum) {
                        res.clear();
                        break;
                    }
                    if (tmp ==sum){
                        result.push_back(res);
                        res.clear();
                        break;
                    }
                }
            }
		}    
		return result;
    }
};

剑指offer思路

双指针问题
当总和小于sum,大指针继续++
否则小指针++

链接:https://www.nowcoder.com/questionTerminal/c451a3fd84b64cb19485dad758a55ebe?f=discussion
来源:牛客网

class Solution {
	public:
		vector<vector<int> > FindContinuousSequence(int sum) {
			vector<vector<int> > result;
			vector<int> res;
			int phigh = 2, plow = 1;
			while (phigh > plow) {
				int cur = (phigh + plow) * (phigh - plow + 1) / 2;//等差数列求和
				if (cur < sum)
					phigh++;

				if (cur == sum) {
					for (int i = plow; i <= phigh; i++)
						res.push_back(i);
					result.push_back(res);
					res.clear();
					plow++;
				}

				if (cur > sum)
					plow++;
			}

			return result;
		}
	};
发布了57 篇原创文章 · 获赞 28 · 访问量 4115

猜你喜欢

转载自blog.csdn.net/weixin_41747893/article/details/104706402