Problem overview
The Collatz sequence starts from a positive integer n and repeats one rule until it reaches 1: if the current number is even, halve it; if it is odd, replace it with three times the number plus one. The Collatz conjecture says the sequence reaches 1 from every positive starting value. Nobody has proved it, but it has been checked by computer for enormous ranges, so the loop below does end for any value you are likely to try.
The method printSeries(self, n) prints every value that n takes, one per line, starting with n itself and ending with 1. For n = 3 it prints 3, 10, 5, 16, 8, 4, 2, 1.
Approach: loop while n is greater than 1
The problem has the shape of a loop: apply the same update over and over until a stop condition holds. The stop condition is "n has reached 1", so the loop continues while n > 1. Inside the loop there are two cases, so it contains an if/else:
- Even
n(n % 2 == 0): the new value isn // 2. - Odd
n: the new value is3 * n + 1.
Because the starting value must also be printed, and the loop prints each new value after computing it, the first print goes before the loop.
Step by step
- Print
nbefore the loop. The series begins with the input itself, and the loop only prints values it has just computed. - Start a
while n > 1loop. Oncenis 1 the sequence is over. Starting from 1, the loop body never runs, so only "1" is printed. - Handle the even case. Test
n % 2 == 0and setn = n // 2. Use//: plain/returns a float in Python, so the printed values would look like8.0instead of8. - Handle the odd case in
else. Setn = 3 * n + 1. - Print
nafter theif/else, at the same indentation as theif, so it runs for both cases.
The solution in Python
class Solution:
def printSeries(self, n: int):
print(n)
while n > 1:
if n % 2 == 0:
n = n // 2
else:
n = 3 * n + 1
print(n)
Python details worth knowing:
- The parameter
nis an ordinary local variable, so the loop may reassign it. The caller's own variable is not affected, because integers are immutable and the method only rebinds its local name. - Indentation defines the blocks. The last
print(n)is inside thewhilebut outside theif/else. Indenting it one level further would put it inside theelse, so even values would never be printed. - Python integers have no size limit, so
3 * n + 1cannot overflow, even if the sequence climbs far above the starting value. Starting from 27, for example, it reaches 9232 before it falls to 1.
Complexity
- Time: proportional to the length of the sequence, which is the number of loop iterations. There is no simple formula for this length in terms of
n. It grows slowly: 27 takes 111 steps, which is far more than 3 takes (7 steps), though 27 is not much bigger. - Space: O(1). The method keeps only the current number.
Edge cases and common mistakes
- Starting at 1. The output is the single line
1. - Forgetting the first print. The output would then miss the starting value: for
n = 3it would begin with 10. - Printing before the update. If the loop printed first and then updated, the last value (1) would never be printed, or would need a separate print after the loop.
- Using
/for the even case. The values after the first halving turn into floats: forn = 3the output would contain5.0instead of5. - Writing
while n != 1. The conjecture is about positive integers. Withn = 0a!= 1test loops forever, because 0 halves to 0, whilewhile n > 1stops at once on 0 and on negative numbers.
Testing
Calling Solution().printSeries(6) prints:
6
3
10
5
16
8
4
2
1
Starting from 6 halves to 3, and from there the sequence is the one for 3 above.
