一、题目
输入一个正整数 target
,输出所有和为 target
的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
1 |
|
示例 2:
1 |
|
限制:
1 <= target <= 10^5
二、思考
- 枚举 + 暴力
当然,如果你想直接从 1 遍历至 target ,写两层循环,也是可以暴力解决此问题。不过时间复杂度就相对比较大了。
根据官方解法:枚举每个正整数为起点,判断以它为起点的序列之和 sum 是否等于 target 即可。当然,我们不可能从 1 至 target 挨个枚举出来。所以给出枚举的上限: target / 2
。在 C 中遇到奇数则是向下取整。
- 双指针
其实就是两个指针指向闭区间的区间端点,而这个闭区间内数之和就是 target。
设闭区间为 [l, r]
,我们可以列出公式(等差数列求和公式)
target = (l + r) * (r - l + 1) / 2
使用双指针时,总会遇到所求和 sum 与 target 大小不等的时候。
当 sum < target 时,r++ ,是为了扩大区间长度。
当 sum > target 时,l++ ,是为了区间向左移动,重新求和。
三、代码实现
枚举 + 暴力
1 |
|
双指针
1 |
|