Given a positive integer n
, find the number of ways it can be written as the sum of consecutive positive integers. Each sequence must consist of at least one integer, and the integers must be positive and consecutive. For example, 9
can be written as 2 + 3 + 4
, 4 + 5
, or just 9
itself.
Your task is to return the total number of possible ways to express n
as the sum of one or more consecutive positive integers.
n
itself) are valid.n
(1 ≤ n
≤ 109)
To solve this problem, let's first think about what it means to write n
as the sum of consecutive positive integers. For example, for n = 9
:
The brute-force way would be to try all possible sequences of consecutive numbers and check which ones sum to n
. However, this would be too slow for large n
. So, we need to look for a mathematical pattern or formula that helps us count the number of valid sequences efficiently.
Let's observe that the sum of k
consecutive numbers starting from x
is:
n = x + (x+1) + (x+2) + ... + (x+k-1) = kx + k(k-1)/2
Rearranged: n = kx + k(k-1)/2
. So, n - k(k-1)/2 = kx
.
Thus, (n - k(k-1)/2)
must be divisible by k
and x > 0
.
This gives us a way to check for each possible value of k
(number of terms in the sequence) whether there's a valid x
(start of the sequence) that makes the sum equal to n
.
Let's break down the steps to efficiently count the number of ways to write n
as the sum of consecutive positive integers:
k
(sequence length) starting from 1, compute k(k-1)/2
(sum of the first k-1
integers).
n - k(k-1)/2
is positive; if not, stop (as sequences longer than this can't start with a positive integer).
n - k(k-1)/2
is divisible by k
, then there exists a positive integer x
such that the sequence x, x+1, ..., x+k-1
sums to n
.
k
, increment the count.
k(k-1)/2 < n
.
This approach is efficient because the value k(k-1)/2
grows quadratically, so the loop runs only up to about O(√2n)
iterations.
Let's illustrate the process with n = 15
:
So, there are 4 valid ways: [15], [7,8], [4,5,6], [1,2,3,4,5].
Brute-force approach:
For each possible starting number, try all possible sequence lengths, summing up until the total is at least n
. This is O(n)
or worse, which is too slow for large n
.
Optimized approach:
We only need to check up to k
where k(k-1)/2 < n
. Since k^2
grows quickly, the number of iterations is about O(√n)
.
Time Complexity: O(√n)
Space Complexity: O(1)
(just a counter variable)
The key insight is transforming the problem into a mathematical equation relating n
, the sequence length k
, and the starting number x
. By iterating over possible sequence lengths and checking divisibility, we can efficiently count the valid consecutive sums in O(√n)
time. This avoids brute-force enumeration and leverages arithmetic properties for an elegant and efficient solution.
class Solution:
def consecutiveNumbersSum(self, n: int) -> int:
count = 0
k = 1
while k * (k - 1) // 2 < n:
if (n - k * (k - 1) // 2) % k == 0:
x = (n - k * (k - 1) // 2) // k
if x > 0:
count += 1
k += 1
return count
class Solution {
public:
int consecutiveNumbersSum(int n) {
int count = 0;
for (long long k = 1; k * (k - 1) / 2 < n; ++k) {
if ((n - k * (k - 1) / 2) % k == 0) {
int x = (n - k * (k - 1) / 2) / k;
if (x > 0)
++count;
}
}
return count;
}
};
class Solution {
public int consecutiveNumbersSum(int n) {
int count = 0;
for (long k = 1; k * (k - 1) / 2 < n; ++k) {
if ((n - k * (k - 1) / 2) % k == 0) {
long x = (n - k * (k - 1) / 2) / k;
if (x > 0)
count++;
}
}
return count;
}
}
var consecutiveNumbersSum = function(n) {
let count = 0;
let k = 1;
while (k * (k - 1) / 2 < n) {
if ((n - k * (k - 1) / 2) % k === 0) {
let x = (n - k * (k - 1) / 2) / k;
if (x > 0) count++;
}
k++;
}
return count;
};