Problem overview
The Collatz sequence starts from any positive integer and repeats one rule. If the current number is even, halve it. If it is odd, multiply it by 3 and add 1. The conjecture says that every positive starting number eventually reaches 1. Nobody has proved it, but it has been checked by computer for an enormous range of starting values.
The method printSeries receives an int named n and prints every value that n takes, one per line, starting with n itself and stopping when the value reaches 1. For n = 3 the output is 3, 10, 5, 16, 8, 4, 2, 1. The method prints and returns nothing, which is why its return type is void.
Approach: repeat a step until a condition fails
You do not know in advance how many steps the sequence needs. For n = 6 it takes 8 steps, and for n = 27 it takes 111. A for loop with a fixed count does not fit this problem, but a while loop does, since it runs as long as a condition holds and the number of repeats is not known up front.
The loop condition is n > 1: the sequence ends when 1 is reached. Inside the loop there are two cases, even and odd, which is a natural if and else. Each pass computes the next term and prints it.
The first value, n itself, has to be printed before the loop, since the loop only prints the values it produces. That also makes the case n = 1 work: the loop body never runs, and the output is the single line 1.
Here is the sequence for n = 6, written the way the loop sees it:
6
3
10
5
16
8
4
2
1
6 is even, so it becomes 3. 3 is odd, so it becomes 3 * 3 + 1 = 10. From there 10 gives 5, 5 gives 16, and then halving takes 16 down through 8, 4 and 2 to 1.
Step by step
- Print
nwithSystem.out.printlnbefore the loop. The sequence includes its starting value. - Write a
whileloop that runs whilen > 1. The parameternis an ordinary local variable inside the method, so the loop can change it directly. - Handle the even case. An even number has remainder 0 when divided by 2, so the test is
n % 2 == 0. Thenn = n / 2. Dividing twointvalues truncates the fraction, and the division is exact here becausenis even. - Handle the odd case in the
elsebranch. Setn = 3 * n + 1. Any number that is not even is odd, so no second condition is needed. - Print the new
nafter theelseblock, still inside the loop. This line runs for both branches, so each new term is printed once, right after it is produced.
The solution in Java
class Solution {
public void printSeries(int n) {
System.out.println(n);
while (n > 1) {
if (n % 2 == 0) {
n = n / 2;
} else {
n = 3 * n + 1;
}
System.out.println(n);
}
}
}
A few Java notes:
- Parameters are copies. Java passes
intby value, so changingninside the method does not affect the caller's variable. That is why reusing the parameter as the loop variable is safe. - Both branches print the same way. The
printlnsits after theif/else, not inside each branch. Copying it into both branches also works, but a single line is easier to maintain. - The test is
% 2 == 0. For positive numbers you could also writen % 2 == 1for odd. Testing for even is safer in general, because in Java-7 % 2is -1, not 1.
Complexity
The running time is the number of terms in the sequence. Nobody has a formula for it. It grows slowly, though: starting from 27 the sequence has 111 steps and climbs as high as 9232 before it falls to 1. The method stores nothing except the current number, so its extra space is O(1).
Edge cases and common mistakes
- Starting with 1. The output is just
1. The loop condition is false at once. - Printing in the wrong place. Without the first
println, the output for 3 starts with 10. If the loop printednat the top of its body instead of at the bottom, the final 1 would never appear, because the loop stops before it comes back to that line. - Using
n >= 1as the condition. This is an infinite loop. From 1 the odd rule gives 4, then 2, then 1 again, and the loop never ends. - Forgetting the
else. With two separateifstatements, an even number is halved and the secondifthen looks at the already-changed value, which can apply both rules in one pass. - Overflow with large starting values. The terms can grow well beyond the starting number, and an
intstops at 2,147,483,647. Starting from 113383, the sequence reaches 2,482,111,348, which does not fit. After 120 steps the value wraps to a negative number, the conditionn > 1turns false, and the output stops at -1812855948. For large inputs, declare the variable aslong. - Starting from 0 or a negative number. The conjecture is about positive integers. The method prints the starting value and stops at once, because the loop condition is false.
Testing
Try n = 3, which prints 3, 10, 5, 16, 8, 4, 2, 1. Try n = 1, which prints only 1, and n = 7, which prints 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1.
