题目描述
输入一个正整数 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
n
n项和为:
S = n a 1 + n ( n − 1 ) d 2 S=na_1+\frac{n(n-1)d}{2} S=na1+2n(n−1)d - 本题中要求连续正整数,则
d
=
1
d=1
d=1,我们需要求出
n
n
n和
a
1
a_1
a1。
整理上式,得:
a 1 = S n − n − 1 2 = 2 S − n ( n − 1 ) 2 n a_1=\frac{S}{n}-\frac{n-1}{2}=\frac{2S-n(n-1)}{2n} a1=nS−2n−1=2n2S−n(n−1) -
S
S
S为题目中的
target
,仅当 2 S − n ( n − 1 ) 2 n \frac{2S-n(n-1)}{2n} 2n2S−n(n−1)为正整数时,满足条件,因此可以遍历 n n n,分别检查计算得到的 a 1 a_1 a1是否为正整数,是则将答案存入待输出数组。 - 此外,还可以确定
n
n
n的范围,来减少查找时间,已知前
n
n
n个自然数的和为
n
(
n
+
1
)
2
\frac{n(n+1)}{2}
2n(n+1),则若
n
(
n
+
1
)
2
=
S
\frac{n(n+1)}{2}=S
2n(n+1)=S时,
n
n
n取到最大值:
n m a x = 2 S n_{max}=\sqrt{2S} nmax=2S - 得到 n n n的取值范围为 [ 2 , ⌊ 2 S ⌋ ] [2,\lfloor \sqrt{2S} \rfloor] [2,⌊2S⌋],分别代入上式检查 a 1 a_1 a1是否为正整数即可。
代码实现
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;
}
};