0829 - Consecutive Numbers Sum (Hard)
Problem Link
https://leetcode.com/problems/consecutive-numbers-sum/
Problem Statement
Given an integer n
, return the number of ways you can write n
as the sum of consecutive positive integers.
Example 1:
Input: n = 5
Output: 2
Explanation: 5 = 2 + 3
Example 2:
Input: n = 9
Output: 3
Explanation: 9 = 4 + 5 = 2 + 3 + 4
Example 3:
Input: n = 15
Output: 4
Explanation: 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
Constraints:
1 <= n <= 10^9
Approach: Math
The first observation is that itself is one of the answer. We can define .
Let be the first number of the sequence, then we should have
We can arrange the formula. First there are terms of so we can just multiply them together. The remaining sum is just which is . Why? We can get that from sum of terms in Arithmetic Progress (A.P.) formula
where is the first term and is the common difference.
We can further transform from
to the following expression
where is the last term and it is equivalent to .
Back to our problem, from , we can see that the first term is 0 and and last term is . Therefore, we can know that .
Now we have , which means we can construct a sum of using terms starting from if is a multiple of . We can iterate and check if this statement is true or not. The next problem would be "What is the range of ?".
Since itself is already considered, so we need to start from 2. From the above formula, needs to be greater than 0.
The upper bound for approximately would be around . Therefore, we iterate from to to check if is a multiple of . If so, it means we have one sequence so we increase the answer by .
class Solution {
public:
int consecutiveNumbersSum(int n) {
int ans = 1;
// n = x + (x + 1) + (x + 2) + ... + (x + (k - 1))
// n = k * x + k * (k - 1) / 2
// k * x = n - k * (k - 1) / 2
// n - k * (k - 1) / 2 > 0
// k * (k - 1) < 2 * n
// ~= k * k < 2 * n + k
for (int k = 2; k < sqrt(2 * n + k); k++) {
ans += (n - (k * (k - 1) / 2)) % k == 0;
}
return ans;
}
};