Leetcode
412. Fizz Buzz
难度:简单
给你一个整数 n ,找出从 1
到 n
各个整数的 Fizz Buzz
表示,并用字符串数组 answer
(下标从 1 开始)返回结果,其中:
answer[i] == "FizzBuzz"
如果i
同时是3
和5
的倍数。answer[i] == "Fizz"
如果i
是3
的倍数。answer[i] == "Buzz"
如果i
是5
的倍数。answer[i] == i
(以字符串形式)如果上述条件全不满足。
示例 1:
输入:n = 3
输出:[“1”,“2”,“Fizz”]
示例 2:
输入:n = 5
输出:[“1”,“2”,“Fizz”,“4”,“Buzz”]
示例 3:
输入:n = 15
输出:[“1”,“2”,“Fizz”,“4”,“Buzz”,“Fizz”,“7”,“8”,“Fizz”,“Buzz”,“11”,“Fizz”,“13”,“14”,“FizzBuzz”]
提示:
1 <= n <= 104
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fizz-buzz
代码1:
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> answer(n); // 创建一个大小为n的字符串向量
// 遍历从1到n的整数
for (int i = 1; i <= n; i++) {
// 判断当前整数是否是3和5的倍数
if (i % 3 == 0 && i % 5 == 0) {
answer[i - 1] = "FizzBuzz";
}
// 判断当前整数是否是3的倍数
else if (i % 3 == 0) {
answer[i - 1] = "Fizz";
}
// 判断当前整数是否是5的倍数
else if (i % 5 == 0) {
answer[i - 1] = "Buzz";
}
// 如果上述条件都不满足,将整数转换为字符串并存储
else {
answer[i - 1] = to_string(i);
}
}
return answer; // 返回Fizz Buzz表示的字符串数组
}
};
代码2:
/* 在这个优化后的解决方案中,我们遍历从1到n的整数,并在每次迭代时使用一个字符串变量`current`来存储当前整数的Fizz Buzz表示。通过在每个条件下仅更新`current`字符串,我们避免了多个分支判断,并减少了代码重复。
简要解释代码:
1. 初始化一个大小为n的字符串向量`answer`。
2. 遍历从1到n的整数。
3. 对于每个整数i,创建一个空字符串`current`。
4. 如果i是3的倍数,在`current`后追加"Fizz"。
5. 如果i是5的倍数,在`current`后追加"Buzz"。
6. 如果`current`为空字符串(即i既不是3的倍数也不是5的倍数),将i转换为字符串并赋值给`current`。
7. 将`current`存储到结果数组`answer`的相应位置。
8. 返回结果数组`answer`。 */
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> answer(n); // 创建一个大小为n的字符串向量
// 遍历从1到n的整数
for (int i = 1; i <= n; i++) {
string current = "";
// 判断当前整数是否是3的倍数
if (i % 3 == 0) {
current += "Fizz";
}
// 判断当前整数是否是5的倍数
if (i % 5 == 0) {
current += "Buzz";
}
// 如果current为空字符串,将整数转换为字符串并存储
if (current.empty()) {
current = to_string(i);
}
// 将当前整数的Fizz Buzz表示存储到结果数组中
answer[i - 1] = current;
// 打印当前字符串的值
cout << current << endl;
}
return answer; // 返回Fizz Buzz表示的字符串数组
}
};
代码3:
/* 这个解决方案与之前提供的解决方案非常相似,主要区别在于:
1. 这个解决方案没有预先分配结果向量`answer`的大小,而是使用`emplace_back`动态地添加元素。
2. 这个解决方案使用`curr.size() == 0`而不是`curr.empty()`来判断`curr`是否为空字符串。在实际使用中,两者效果相同。 */
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> answer;
for (int i = 1; i <= n; i++) {
string curr;
if (i % 3 == 0) {
curr += "Fizz";
}
if (i % 5 == 0) {
curr += "Buzz";
}
if (curr.size() == 0) {
curr += to_string(i);
}
/* `answer.emplace_back(curr);`:将`curr`添加到结果向量`answer`的末尾。
`emplace_back`函数与`push_back`类似,但通常更高效,因为它可以直接在向量中构造元素,而无需临时复制。 */
answer.emplace_back(curr);
}
return answer;
}
};
分析:
以下是对这三种Fizz Buzz问题的C++实现的分析:
解决方案1:
这个解决方案首先创建了一个大小为n的字符串向量answer
。接下来,它遍历从1到n的整数,并使用if-else
语句检查当前整数是否是3的倍数、5的倍数或3和5的倍数。然后,根据条件将"Fizz"、"Buzz"、"FizzBuzz"
或整数本身(转换为字符串)
存储在answer
向量的相应位置。这个解决方案是最直接的实现方法,使用了简单的if-else
语句结构。
解决方案2:
这个解决方案也首先创建了一个大小为n的字符串向量answer
。它使用了两个独立的if语句来检查当前整数是否是3的倍数或5的倍数。如果整数是3的倍数,它将"Fizz"添加到current
字符串中;如果整数是5的倍数,它将"Buzz"添加到current
字符串中。如果current
为空字符串(即当前整数既不是3的倍数也不是5的倍数),则将整数本身(转换为字符串)存储在current
中。最后,将current
存储在answer
向量的相应位置。这个解决方案避免了使用嵌套的if-else语句,使代码更简洁易读。
解决方案3:
这个解决方案创建了一个空字符串向量answer
。与解决方案2类似,它使用两个独立的if语句来检查当前整数是否是3的倍数或5的倍数。在遍历结束时,使用answer.emplace_back(curr);
将curr
添加到answer
向量的末尾。emplace_back
与push_back
类似,但通常更高效,因为它可以直接在向量中构造元素,而无需临时复制。这个解决方案在内存分配方面可能更高效,因为它在向量answer
中逐个添加元素,而不是预先分配大小。
总结:
- 解决方案1使用了最直接的if-else语句结构,可读性较好,但可能不是最简洁的实现。
- 解决方案2避免了使用嵌套的if-else语句,使代码更简洁易读。它也预先分配了向量
answer
的大小,可能在内存分配方面效率较低。 - 解决方案3与解决方案2类似,但在内存分配方面可能更高效,因为它在向量
answer
中逐个添加元素,而不是预先分配大小。
根据具体需求和优先级,可以根据这些解决方案的特点选择最合适的实现方法。
如果代码可读性和简洁性是首要目标,那么解决方案2可能是最佳选择。它避免了嵌套的if-else语句,使代码更加清晰。同时,它预先分配了向量answer
的大小,可能在内存分配方面效率较低,但对于Fizz Buzz这种简单问题,这个性能差异可能并不明显。
如果内存分配效率是优先考虑的因素,那么解决方案3可能是最佳选择。通过使用emplace_back
方法逐个添加元素,它可以在向量answer
中直接构造元素,而无需临时复制。此外,它也避免了使用嵌套的if-else语句,使代码更加简洁。
解决方案1可以作为一个更直观的实现方法,特别是对于初学者或者对Fizz Buzz问题不太熟悉的人。然而,它的代码相对冗长,可能不是最优的实现方式。
总之,在选择最佳实现时,需要根据具体的需求和优先级进行权衡。在实际编程过程中,可以尝试不同的实现方法,并分析它们的优缺点,以便找到最适合特定场景的解决方案。