Given a positive integer N
, how many ways can we write it as a sum of consecutive positive integers?
Example 1:
Input: 5 Output: 2 Explanation: 5 = 5 = 2 + 3Example 2:
Input: 9 Output: 3 Explanation: 9 = 9 = 4 + 5 = 2 + 3 + 4Example 3:
Input: 15 Output: 4 Explanation: 15 = 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
Note: 1 <= N <= 10 ^ 9
.
连续整数求和。题意很简单,给一个正整数N,请你返回有多少组连续正整数满足所有数字之和为N。
这是一道数学题。没做过的话面试的时候确实不太好想。对于任何一个正整数N来说,首先他自己单独就可以是一个等差数列,另外,比如题目中的第三个例子,15可以有三种拆解方法。但是不管怎么样,参与加法的数字们是一个差值为1的等差数列,同时这个等差数列不一定是从1开始。所以我们要做的就是尽快确定满足条件的等差数列的第一个数字都有哪些。假设某一个等差数列是从X开始的,且有K个数字,那么这个等差数列应该是类似这样
X, X + 1, X + 2, ...X + K - 1 = N
同时这个等差数列的和可以写成这样,(首项 + 末项)* 项数 / 2,并且化简得到KX + (k^2 - k) / 2 = N。这里自己手算一下。
(X + X + K - 1) * K / 2 = KX + (k^2 - k) / 2 = N
由于我们现在要找的是X(等差数列的第一个数字),所以这里可以把公式稍微变动一下,得到如下
KX = N - (k^2 - k) / 2
在这种情况下,我们只要能找到X的整数解,就能找到对应的等差数列。这里我们可以对K找一个范围,下界至少是1,因为等差数列至少存在一个数字;对于上界,我们可以把上面这个公式 KX = N - (K^2 - K) / 2 再稍微变形一下。在这个公式中,因为X必须是正整数,所以起码可以得到如下结论
N - (K^2 - K) / 2 > 0 -> K^2 - K > 2N
所以可以得到K是小于Math.sqrt(2N)的。整理得到K的范围是1 - Math.sqrt(2N)。
有了K的范围之后,,再根据这个公式,KX = N - (k^2 - k) / 2,就可以根据这个范围开始找可以被整除的X,res初始化为1(因为数字N本身也可以视作一个等差数列)。因为N知道了,K也有范围了,所以要做的就是看看把N和K带入这个公式之后,是否能得到一个整除的X。
时间O(1) - 只要计算sqrt(2N)次即可
空间O(1)
Java实现
1 class Solution { 2 public int consecutiveNumbersSum(int N) { 3 int res = 1; 4 for (int k = 2; k < Math.sqrt(2 * N); k++) { 5 if ((N - k * (k - 1) / 2) % k == 0) { 6 res++; 7 } 8 } 9 return res; 10 } 11 }