剑指 Offer 57 - II. 和为s的连续正数序列

题目描述

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例1:

输入:target = 9
输出:[[2,3,4],[4,5]]

示例2:

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

限制:

1 <= target <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof

思路解析

  • 等差数列的前\(n\)项和为:

\[S=na_1+\frac{n(n-1)d}{2} \]

  • 本题中要求连续正整数,则\(d=1\),我们需要求出\(n\)\(a_1\)
    整理上式,得:

\[a_1=\frac{S}{n}-\frac{n-1}{2}=\frac{2S-n(n-1)}{2n} \]

  • \(S\)为题目中的target,仅当\(\frac{2S-n(n-1)}{2n}\)为正整数时,满足条件,因此可以遍历\(n\),分别检查计算得到的\(a_1\)是否为正整数,是则将答案存入待输出数组。
  • 此外,还可以确定\(n\)的范围,来减少查找时间,已知前\(n\)个自然数的和为\(\frac{n(n+1)}{2}\),则若\(\frac{n(n+1)}{2}=S\)时,\(n\)取到最大值:

\[n_{max}=\sqrt{2S} \]

  • 得到\(n\)的取值范围为\([2,\lfloor \sqrt{2S} \rfloor]\),分别代入上式检查\(a_1\)是否为正整数即可。

代码实现

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        vector<vector<int>> result;
        int max_add = (int)(sqrt(2 * target));
        for(int i = max_add; i > 1; i--) {
            int p = 2 * target - i * (i - 1);
            int q = 2 * i;
            if(p % q == 0) {
                int a1 = p / q;
                vector<int> tmp;
                for(int j = 0; j < i; j++)
                    tmp.push_back(j + a1);
                result.push_back(tmp);
            }
        }
        return result;
    }
};
posted @ 2020-09-09 11:39  行者橙子  阅读(130)  评论(0编辑  收藏  举报