What the FizzBuzz problem asks
FizzBuzz is one of the most common first coding exercises. Given a positive integer n, the method fizzBuzz(int n) prints the numbers from 1 to n, one per line, with three exceptions:
- a multiple of 3 prints
Fizzinstead of the number; - a multiple of 5 prints
Buzzinstead of the number; - a multiple of both 3 and 5 prints
FizzBuzz.
The method returns nothing (void). Its result is the text it prints. For n = 15 the output is 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, each item on its own line. The required cost is O(n) time and O(1) extra space.
Approach: one loop, one decision per number
The numbers are independent of each other, so there is nothing to remember between them. A for loop visits each number from 1 to n, and inside the loop an if / else if chain picks what to print.
The test for "multiple of 3" is the remainder operator: i % 3 == 0 is true when dividing i by 3 leaves nothing over. A number that is a multiple of both 3 and 5 is a multiple of 15, because 3 and 5 share no factor. So i % 15 == 0 identifies the FizzBuzz case with a single test.
For example, 9 % 3 is 0 because 3 goes into 9 exactly three times, while 10 % 3 is 1 because 10 is three threes plus 1 left over. Only a remainder of 0 means "multiple". Both operands here are int values, so the result is an int as well, and the comparison with 0 gives a boolean the if can use directly.
The order of the checks matters. Every multiple of 15 is also a multiple of 3 and of 5, and an else if chain stops at the first condition that is true. If the check for 3 came first, 15 would print Fizz and never reach the FizzBuzz branch. The most specific case, 15, goes first.
Step by step
- Loop from 1 to
ninclusive. The loop variable starts at 1, not 0, and the condition isi <= nso thatnitself is included. - Test for 15 first. If
i % 15 == 0, printFizzBuzz. - Then test for 3. If
i % 3 == 0, printFizz. - Then test for 5. If
i % 5 == 0, printBuzz. - Otherwise print the number itself.
System.out.println(i)prints theintand ends the line.
The solution in Java
class Solution {
public void fizzBuzz(int n) {
for (int i = 1; i <= n; i++) {
if (i % 15 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
}
}
A few Java details are worth knowing:
printlnversusprint.System.out.printlnadds a line break after its argument, which is what "each on a new line" requires.System.out.printdoes not.- One method, two kinds of argument.
printlnis overloaded, so the same call prints aStringsuch as"Fizz"and anintsuch asi. No conversion is needed. - Exact text. The words are case-sensitive:
"Fizzbuzz"or"Fizz Buzz"would not match the expected output.
An alternative: build the word from parts
Some programmers avoid the test for 15 by building the output string. For each number, start with an empty string, append Fizz if the number is a multiple of 3 and Buzz if it is a multiple of 5, and print the number only when the string is still empty:
for (int i = 1; i <= n; i++) {
String out = "";
if (i % 3 == 0) out += "Fizz";
if (i % 5 == 0) out += "Buzz";
System.out.println(out.isEmpty() ? String.valueOf(i) : out);
}
It prints the same lines. For 15 both if statements run, so the string becomes FizzBuzz. This version scales better if a rule such as "multiples of 7 print Bazz" is added later, because each rule is one more independent if rather than a new combination to place in the chain.
Complexity
The loop runs exactly n times and each iteration does a fixed amount of work (a few remainder operations and one print), so the time is O(n). The only variable the method creates is the loop counter i, so the extra space is O(1). The method prints as it goes and never stores the sequence.
Common mistakes
- Checking 3 or 5 before 15. With this order the output for 15 is wrong:
if (i % 3 == 0) System.out.println("Fizz");
else if (i % 5 == 0) System.out.println("Buzz");
else if (i % 15 == 0) System.out.println("FizzBuzz"); // never reached
else System.out.println(i);
For i = 15 this prints Fizz, because the first condition is already true. The FizzBuzz branch can never run.
- Starting at 0.
0 % 15 == 0is true, so a loop that starts at 0 prints a strayFizzBuzzfirst. - Using
<instead of<=. The last number,n, is silently missing. - Using
=instead of==.i % 3 = 0does not compile, because=assigns and==compares. - Returning a list instead of printing. The method is
voidand is checked by what it prints, so collecting the strings in a list and returning them does not do the job.
Testing
Try n = 1, which prints only 1; n = 3, which prints 1, 2, Fizz; n = 5, which ends with Buzz; and n = 15, which ends with FizzBuzz. If those four are right, the three special cases and the plain case are all covered.
