LeetCode 412. Fizz Buzz
本节目标
用规则优先级完成逐项模拟,并理解重叠条件必须先判断更具体的分支。
这道题是模拟、递推与边界的第一道母题:从 1 到 n 逐项处理,把规则的优先级直接写成分支顺序。
题意与约束
对每个整数 i:3 的倍数输出 Fizz,5 的倍数输出 Buzz,同时是两者倍数时输出 FizzBuzz,其余情况输出整数本身。答案按从 1 到 n 的顺序组成字符串列表。
1 <= n <= 10^4
从规则到分支顺序
答案数组 answer 保存已经处理的所有结果。每轮只处理当前 i,按规则追加一个字符串;循环结束时,数组恰好对应从 1 到 n 的全部输出。
为什么先判断 15
“同时是 3 和 5 的倍数”就是 15 的倍数,属于更具体的重叠规则。若先判断 3,15 会直接输出 Fizz,永远到不了 FizzBuzz 的分支。因此必须先判断 15,再判断 3 和 5。
代码实现
两份源码都按同一优先级判断,并由页面直接展示自动测试实际执行的文件。
- C++
- Python
C++17
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> answer;
for (int i = 1; i <= n; i++) {
if (i % 15 == 0) {
answer.push_back("FizzBuzz");
} else if (i % 3 == 0) {
answer.push_back("Fizz");
} else if (i % 5 == 0) {
answer.push_back("Buzz");
} else {
answer.push_back(to_string(i));
}
}
return answer;
}
};
Python 3
class Solution:
def fizzBuzz(self, n: int) -> list[str]:
answer = []
for i in range(1, n + 1):
if i % 15 == 0:
answer.append("FizzBuzz")
elif i % 3 == 0:
answer.append("Fizz")
elif i % 5 == 0:
answer.append("Buzz")
else:
answer.append(str(i))
return answer
复杂度分析
- 时间复杂度:
O(n),每个整数只判断一次。 - 空间复杂度:
O(n),返回的答案列表包含n个字符串。
易错点
- 先判断 3 或 5,会截走同时满足两条规则的情况。
- 循环必须从 1 开始,并包含
n。 - 返回的是字符串列表,普通数字也要转换成字符串。
模式迁移
这类题的关键不是 Fizz 或 Buzz,而是“重叠规则先处理更具体的条件”。以后遇到状态机、分段计费或多条件分类时,也先列出条件的包含关系,再写分支顺序。