题目描述
输入一个正整数 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} floor]),分别代入上式检查(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;
}
};