For example, when sn = 100, the continuous positive integer series with the sum of 100 has
100
18 19 20 21 22
9 10 11 12 13 14 15 16
For the design of this algorithm, we can most easily think of traversing all the numbers from 1 to sn cyclically, and whether the total starting point of each number recycling calculation is exactly sn. The approximate time complexity of this algorithm is
O (n * log2n), that is to say, when the sn is 1 million, it will take about 20 million cycles. The efficiency is naturally relatively low. Is there a more efficient way than the above method? The answer is yes.
First, let's look at the formula for the sum of the arithmetic difference series:
Sn = n (a1 + an)/2 = na1 + n (n-1)/2
From this formula, we can easily see that when Sn and n are fixed, finding a1 is a linear function:
A1 = (Sn-n (n-1)/2)/n
With this function, it is very easy to optimize this algorithm. We only need to traverse n from 1 until (Sn-n (n-1)/2) <n, we can find all the continuous sequences that meet the conditions. The algorithm complexity is the square root of 2N, that is, when Sn = 1 million, you only need to loop 1414 times to get all the series.
Just saw the invitation algorithm: http://www.cnblogs.com/downmoon/archive/2011/03/05/1971400.html
When the algorithm sn is 1 million, the number of loops is 12970034, which is nearly 10 thousand times less efficient than my algorithm.
The following shows my algorithm code.
static void ListSequence(int sn)
{
// Ignore the case where the sn is not a positive integer
if (sn <= 0)
{
return;
}
Int n = 1; // n traversal starts from 1
Int m = sn-n * (n-1)/2; // m is Sn-n (n-1)/2
While (m> = n) // exit the loop when m <n is Sn-n (n-1)/2 <n
{
If (m % n = 0) // if m can be divisible by n, the total number of consecutive positive integer sequences is sn.
{
Int a1 = m/n; // calculate a1
// Print the qualified continuous series
for (int i = a1; i < a1 + n; i++)
{
Console.Write(string.Format("{0} ", i));
}
Console.WriteLine();
}
N ++; // n plus 1
M = sn-n * (n-1)/2; // next m
}
Console. WriteLine ("cycles: {0}", n );
}
When Sn = 100, the running result is:
100
18 19 20 21 22
9 10 11 12 13 14 15 16
Cycles: 14
The following describes the number of cycles from 10 to 10 million for the Sn.
| Sn |
Number of cycles |
| 10 |
5 |
| 100 |
14 |
| 1000 |
45 |
| 10000 |
141 |
| 100000 |
447 |
| 1000000 |
1414 |
| 10000000 |
4472 |