剑指 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;
}
};