829. 连续整数求和
题目描述
给定一个正整数n(1 <= n <= 109 ),求存在多少个“连续正整数和”等于n的数字序列;
如 n = 5 有[5]、 [2 , 3] 两个。 n = 9, [9]、[4,5]、[2,3,4] 三个。
解答思路
1、从组成连续和的数字序列来看,题目要求多少个这样的
数字序列
,即对于不同长度的数字序列
,此长度下的连续和等于n
的个数。
2、对于某长度下数字序列
,最小的是从1
开始,如长度3
,连续和就有[1+2+3,2+3+4,3+4+5...] -> [6,9,12]
,发现数字序列
的连续和是递增
的。由第一步思路来看,如果此长度下存在连续和等于n
的数字序列,只能是有且仅有一个
。
3、我们的解法到目前就是枚举每个长度下是否有连续和等于n
,把每个长度中的和都算一遍?大概率会LTE
,我们再来看数字序列
的连续和[6,9,12,15,18...]
,它是一个递增
的,并且,它是一个等差
的!!这样的话,我们就好处理某个序列长度下,是否存在连续和等于n
的序列了,并且存在的话,还是唯一的!
4、由1、2、3分析可得,对于某一长度下的数字序列
来说,其连续和又可以组成一个序列,且是等差递增
的,在这个序列中有,有仅有一个,或者没有等于n的数。对于这个等差递增序列,首项s1
是确定的s1 = 1+2+3+...+i
(i为数字序列长度),公差d = i
。基于这些推理,即可编写代码
代码c++及注释
class Solution {
public:
int consecutiveNumbersSum(int n) {
int ans = 0;
for(int i = 1; i <= n; i++) //枚举子序列长度 i ,从长度1开始,即包括了n本身,ans = 0
{
int s1 = i * (i + 1) / 2; //长度i下的和 首项s1 组成的序列是s1的递增等差数列 d = i;
if(s1 < n)
{
if((n - s1) % i == 0) //减去首项看是否是d的倍数,即在序列中,且在的话只出现一次
ans++;
}
else if(s1 == n)
ans++;
else
break;
}
return ans;
}
};