Problem overview
FizzBuzz(int n) prints the numbers from 1 to n, one per line, with three substitutions: multiples of 3 become Fizz, multiples of 5 become Buzz, and multiples of both become FizzBuzz.
For n = 15 the output is 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz. Notice that 15 is the first number divisible by both 3 and 5.
Approach
The statement asks for O(n) time and O(1) extra space. A single pass does that: visit each number once, decide what to print, and keep nothing except the loop counter.
The decision rests on divisibility, which the remainder operator % tests. i % 3 == 0 means 3 divides i exactly. The only subtlety is that a multiple of 15 satisfies both the "3" and the "5" tests, so the order of the checks matters.
Step by step
- Loop from 1 to
ninclusive. Aforloop withint i = 1and the conditioni <= nvisits exactly the numbers the task names. Starting at 0 would printFizzBuzzfirst, because 0 is divisible by everything. - Check 15 first. A number divisible by both 3 and 5 is divisible by 15, and it must print
FizzBuzz. If you tested 3 first, 15 would printFizzand never reach the other branches. - Then check 3, then 5. Chained
else ifbranches make sure exactly one thing is printed per number. - Otherwise print the number. The final
elsecovers every number with no special rule.
The solution in C#
class Solution {
public void FizzBuzz(int n) {
for (int i = 1; i <= n; i++) {
if (i % 15 == 0) {
Console.WriteLine("FizzBuzz");
} else if (i % 3 == 0) {
Console.WriteLine("Fizz");
} else if (i % 5 == 0) {
Console.WriteLine("Buzz");
} else {
Console.WriteLine(i);
}
}
}
}
Some C# details:
Console.WriteLinehas overloads for both text and numbers. Passing a string prints the text; passing theintiprints its digits. Each call ends with a line break.- String literals use double quotes. The text
"Fizz"must be spelled and capitalized exactly as the task shows it. - The conditions need parentheses. C# requires them around each
ifcondition, andelse ifis written as two words.
Tracing a few values
Running the chain by hand on a few numbers shows why the order works:
i = 7:7 % 15,7 % 3and7 % 5are 7, 1 and 2, none of them 0, so theelseprints7.i = 9:9 % 15is 9, but9 % 3is 0, so it printsFizz.i = 10:10 % 15is 10 and10 % 3is 1, but10 % 5is 0, so it printsBuzz.i = 30:30 % 15is 0, so it printsFizzBuzzand skips the rest of the chain.
Why 15 and not "3 and 5"
The numbers 3 and 5 share no factor other than 1, so a number is divisible by both exactly when it is divisible by their product, 15. Testing i % 15 == 0 is a shorter way to write i % 3 == 0 && i % 5 == 0. Both are correct, and the second makes the "both" idea more obvious, so use whichever reads better to you.
Another way to avoid the special case is to build the text piece by piece. Start with an empty string, append "Fizz" when 3 divides i, append "Buzz" when 5 divides i, and print the number only if the string is still empty. It produces the same output, but it uses a string variable per iteration, so it is slightly more work than the plain chain. The chain is the clearer choice for this lesson.
Complexity
Time: O(n). The loop runs exactly n times, and each iteration does a constant number of remainder tests and one print.
Space: O(1). The only variable is i. Nothing is collected into a list or a string, because every line is printed as soon as it is decided.
Edge cases and common mistakes
- Wrong branch order. Putting the
% 3test before the% 15test means multiples of 15 printFizz. The usual alternative is to test% 3 == 0 && i % 5 == 0first, which gives the same result as% 15. - Separate
ifstatements instead ofelse if. Without the chain, 15 would match several conditions and print more than once. - Off-by-one on the range.
i < nstops one number early, and the last line of the expected output goes missing. - Small
n. Forn = 1the output is just1. Forn = 3it is 1, 2, Fizz. - Using
=instead of==.i % 3 = 0doesn't compile in C#. The comparison operator is==.
Variations worth knowing
The same structure handles any set of rules. If the task added "multiples of 7 print Bang", you would need a check for every combination in the chain, which grows quickly, and the build-the-text approach becomes the better fit. For this lesson two rules are enough, and the plain chain is easy to read and easy to get right.
Testing
n = 15gives the 15 lines listed above, ending inFizzBuzz.n = 5gives 1, 2, Fizz, 4, Buzz.n = 1gives 1.