LeetCode 412. Fizz Buzz
题目描述


题意分析
按整数
1到n的顺序返回字符串列表。被3整除时对应Fizz,被5整除时对应Buzz,同时被两者整除时对应FizzBuzz,其他数转换成十进制字符串。每个整数只占结果中的一个位置,因此最终列表恰好有
n项。数字范围包含n,不包含零;需要返回这些字符串,而不是让不同条件分别多追加一项。
解法:逐项组合整除规则
核心思路
[!blue]
每个整数的结果只依赖自身是否满足两个整除条件,与前后项无关,所以按顺序逐项判断并追加即可。
Java 用空字符串保存当前结果,先独立判断
3的条件,命中就拼接Fizz;再独立判断5,命中就拼接Buzz。两者同时成立时,两段按顺序合在同一个字符串中;都没命中,字符串仍为空,才转为数字本身。Go 使用互斥的
switch分支,每次只会选择一项,因此先判断同时成立的情况。被3和5同时整除等价于被15整除,先处理它之后,再检查单独的两个条件,最后进入数字转换分支。两种组织方式都保证每个整数只生成一条最终结果,再按照循环顺序放入列表,既覆盖全部情况,也不会重复或打乱顺序。
解题步骤
- 创建结果列表,从
1遍历到n。- 对当前数检查两个整除条件:同时命中生成
FizzBuzz,只命中一个生成对应单词。- 两个条件都未命中时,生成当前整数的十进制字符串。
- 将当前结果追加一次,全部整数处理完后返回列表。
代码实现
class Solution {
public List<String> fizzBuzz(int n) {
List<String> answer = new ArrayList<>();
for (int i = 1; i <= n; ++i) {
String s = "";
if (i % 3 == 0) {
s += "Fizz";
}
if (i % 5 == 0) {
s += "Buzz";
}
if (s.length() == 0) {
s += i;
}
answer.add(s);
}
return answer;
}
}
import (
"strconv"
)
func fizzBuzz(n int) []string {
answer := make([]string, 0, n)
for i := 1; i < n+1; i++ {
switch {
case i%15 == 0:
answer = append(answer, "FizzBuzz")
case i%3 == 0:
answer = append(answer, "Fizz")
case i%5 == 0:
answer = append(answer, "Buzz")
default:
answer = append(answer, strconv.Itoa(i))
}
}
return answer
}
复杂度分析
- 时间复杂度:按固定宽度整数模型为 O(n);若把数字位数 d 单独计入,时间为 O(nd)。
- 空间复杂度:输出空间 O(n),额外空间 O(1);若把数字位数 d 单独计入,输出字符数为 O(nd)。
关键点总结
[!green]
- 两个条件可以同时成立,组合式写法要用独立判断,互斥写法要优先处理交集。
- 拼接顺序固定为先
Fizz后Buzz,两个标签属于同一结果项。- 数字转换是默认情况,每个循环最终都恰好追加一项。
易错点总结
[!yellow]
- 将 Java 两个判断改成
if / else if,会让共同倍数只获得一个标签。- Go 的互斥分支先检查单独的
3或5,共同倍数会被前面的分支截走。- 两次命中分别往列表追加,会增加结果长度,题目需要把标签组合到一项。
- Go 用
string(i)不是十进制数字格式化,应使用strconv.Itoa(i)。- 从零开始或未遍历到
n,都会改变要求的整数范围;单词的大小写与顺序也必须一致。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 1195. 多线程 Fizz Buzz | 中等 | 输出规则相同,原题把不同规则交给不同线程,新增的是同步与输出顺序约束。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!