412. Fizz Buzz

难度简单

写一个程序,输出从 1 到 n 数字的字符串表示。

  1. 如果 n 是3的倍数,输出“Fizz”;

  2. 如果 n 是5的倍数,输出“Buzz”

  3. 如果 n 同时是3和5的倍数,输出 “FizzBuzz”。

示例:

n = 15,返回:
["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"
]

分析

方法一: 模拟法

思路

就像你每次玩 FizzBuzz 那样,你只需要判断这个数是能被 3 整除? 还是能被 5 整除? 或者是都能被整除。

算法

  1. 初始化一个空的答案列表。
  2. 遍历 1 … N。
  3. 对于每个数,判断它能不能同时被 3 和 5 整除,如果可以就把 FizzBuzz 加入答案列表。
  4. 如果不行,判断它能不能被 3 整除,如果可以,把 Fizz 加入答案列表。
  5. 如果还是不行,判断它能不能被 5 整除,如果可以,把 Buzz 加入答案列表。
  6. 如果以上都不行,把这个数加入答案列表。
class Solution {public List<String> fizzBuzz(int n) {// ans listList<String> ans = new ArrayList<String>();for (int num = 1; num <= n; num++) {boolean divisibleBy3 = (num % 3 == 0);boolean divisibleBy5 = (num % 5 == 0);if (divisibleBy3 && divisibleBy5) {// Divides by both 3 and 5, add FizzBuzzans.add("FizzBuzz");} else if (divisibleBy3) {// Divides by 3, add Fizzans.add("Fizz");} else if (divisibleBy5) {// Divides by 5, add Buzzans.add("Buzz");} else {// Not divisible by 3 or 5, add the numberans.add(Integer.toString(num));}}return ans;}
}

复杂度分析

  • 时间复杂度: O(N)
  • 空间复杂度: O(1)

方法二: 字符串连接

思路

这个方法不会降低渐进复杂度,但是当 FizzBuzz 的规则变得更复杂的时候,这将会是个更优雅的解法。比方说,玩个 FizzBuzzJazz 的游戏。规则如下:

3 ---> "Fizz" , 5 ---> "Buzz", 7 ---> "Jazz"

如果你还是用之前的方法来解决这个问题的话,那将会有非常多的条件需要判断哦~

  1. 能不能被 3 整除
  2. 能不能被 5 整除
  3. 能不能被 7 整除
  4. 能不能同时被 3 和 5 整除
  5. 能不能同时被 5 和 7 整除
  6. 能不能同时被 3 和 7 整除
  7. 能不能同时被 3,5,7 整除
  8. 不能被 3,5,7 其中任何一个数整除

如果 FizzBuzz 照着这种方式变地更复杂的话,那么你要写的判断可能会让你抓狂。

算法

我们放弃使用之前的联合判断,取而代之依次判断是否能被给定的数整数。这道题中,就是依次判断能不能被 3 整除,能不能被 5 整除。如果能被 3 整除,就把对应的 Fizz 连接到答案字符串,如果能被 5 整除,就把 Buzz 连接到答案字符串。

举个例子,现在需要判断 15,步骤将会是下面这样的:

条件 1: 15 % 3 == 0, num_ans_str = “Fizz”
条件 2: 15 % 5 == 0, num_ans_str += “Buzz”
=> num_ans_str = “FizzBuzz”

对于 FizzBuzz 来说,只需要判断两个条件就可以了,而不需要像方法一中那样判断三个条件。

同样的,对于 FizzBuzzJazz,现在只需要判断三个条件就可以了。

class Solution {public List<String> fizzBuzz(int n) {// ans listList<String> ans = new ArrayList<String>();for (int num = 1; num <= n; num++) {boolean divisibleBy3 = (num % 3 == 0);boolean divisibleBy5 = (num % 5 == 0);String numAnsStr = "";if (divisibleBy3) {// Divides by 3, add FizznumAnsStr += "Fizz";}if (divisibleBy5) {// Divides by 5, add BuzznumAnsStr += "Buzz";}if (numAnsStr.equals("")) {// Not divisible by 3 or 5, add the numbernumAnsStr += Integer.toString(num);}// Append the current answer str to the ans listans.add(numAnsStr);}return ans;}
}

复杂度分析

  • 时间复杂度: O(N)

  • 空间复杂度: O(1)

方法三 用散列表

思路

这个方法是对方法二的优化。当数字和答案的映射是定好的,那么方法二用起来也还可以。但是如果你遇到一个变态的面试官,他跟你说他需要更自由的映射关系呢?

每个映射一个判断显然是不可行的,这样写出来的代码一定是丑陋不堪且难以维护的。

如果老板有这样一个需求,明天你把映射关系换掉或者删除一个映射关系吧。对于这种要求,我们只能一个个去修改判断条件的代码。

但我们实际上有个更优雅的做法,那就是把映射关系放在 散列表 里面。

算法

  1. 把所有的映射关系放在散列表 fizzBuzzHash 中,这个散列表形如 { 3: 'Fizz', 5: 'Buzz' }
  2. 遍历 1 … N。
  3. 对于每个数字,遍历 fizzBuzzHash 中的键,检查是否能被它整除。
  4. 如果这个数能被键整除,就把当前键映射的值加到到答案字符串后面去。对于散列表的每个键值对,都这样操作。
  5. 最后将答案字符串加入答案列表。

通过这样的方式你可以对散列表添加/删除映射关系,同时还不需要修改太多代码。

而对于 FizzBuzzJazz 这个问题,散列表就可以是这样的,{ 3: 'Fizz', 5: 'Buzz', 7: 'Jazz' }

class Solution {public List<String> fizzBuzz(int n) {// ans listList<String> ans = new ArrayList<String>();// Hash map to store all fizzbuzz mappings.HashMap<Integer, String> fizzBizzDict =new HashMap<Integer, String>() {{put(3, "Fizz");put(5, "Buzz");}};for (int num = 1; num <= n; num++) {String numAnsStr = "";for (Integer key : fizzBizzDict.keySet()) {// If the num is divisible by key,// then add the corresponding string mapping to current numAnsStrif (num % key == 0) {numAnsStr += fizzBizzDict.get(key);}}if (numAnsStr.equals("")) {// Not divisible by 3 or 5, add the numbernumAnsStr += Integer.toString(num);}// Append the current answer str to the ans listans.add(numAnsStr);}return ans;}
}

复杂度分析

  • 时间复杂度: O(N)
  • 空间复杂度: O(1)

【leetcode】412.Fizz Buzz (三种方法开阔思路,java实现)相关推荐

  1. leetcode 412. Fizz Buzz

    Write a program that outputs the string representation of numbers from 1 to n. But for multiples of ...

  2. 算法--生成m个指定范围的不重复随机数的三种方法分析(Java实现)

    Q题目 如何产生m个在0-N范围内的无重复的随机数(不包含N) A解法 2.1 常见解法有两种: 1.间接获取--采用随机下标从已实例化的数组中取元素 2.直接获取随机数--然后一一排除 2.2 间接 ...

  3. 【leetcode】289.生命游戏 (三种解法开阔思路,java实现)

    289. 生命游戏 难度中等 根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个 ...

  4. java equals 判断空_Java 判断字符串是否为空的三种方法与性能分析

    [java中判断字符串是否为数字的三种方法  1>用JAVA自带的函数 public static boolean isNumeric(String str){   for (int i = s ...

  5. Java创建线程的三种方法

    这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...

  6. 中文文本关键词抽取的三种方法(TF-IDF、TextRank、word2vec)

    链接地址:https://github.com/AimeeLee77/keyword_extraction 1.基于TF-IDF的文本关键词抽取方法 词频(Term Frequency,TF) 指某一 ...

  7. 计算两个数平均值的三种方法

    第一种方法: 思路:两数相加求和再除2 代码 int a=10;int b=20;int avg=0;avg=(a+b)/2;//平局值//或者avg=(a+b)>>1://右移表示除2, ...

  8. java中从键盘输入的三种方法以及Console输入

    java中从键盘输入的三种方法: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...

  9. 中文文本关键词抽取的三种方法-python

    利用Python实现中文文本关键词抽取的三种方法 转自github 文本关键词抽取,是对文本信息进行高度凝练的一种有效手段,通过3-5个词语准确概括文本的主题,帮助读者快速理解文本信息.目前,用于文本 ...

最新文章

  1. MySQL count(*)空表为何会很慢
  2. 【网友的】《一个程序猿的生命周期》读后感
  3. html mint ui,vue mint-ui初次使用总结
  4. 操作系统基础:计算机作业管理知识笔记
  5. [转载]十四步实现拥有强大AI的五子棋游戏
  6. python数据结构 树_Python数据结构——AVL树的实现
  7. matlab for循环不覆盖,Matlab for 多个变量循环能不能这样啊 ,求教高手!!!!...
  8. 微课|中学生可以这样学Python(例4.1):快速判断素数
  9. 给radio添加点击事件
  10. 洛谷P1136 迎接仪式
  11. mate50 鸿蒙,华为Mate50Pro概念机:瀑布环绕屏+鸿蒙系统,就算涨价我也劝你买...
  12. 空间和时间 ----节选《时间简史》 霍金
  13. 112-smart-toc-2021-09-09
  14. 网页版简易计算器(仅加减乘除)
  15. 积分球式光源色温校准
  16. 《Android开发从零开始》——3.第一个Android程序
  17. 算法-动态规划 Dynamic Programming--从菜鸟到老鸟
  18. Windows Vista正式版何时提供下载
  19. BLY-HT-450无线温度传感器
  20. xml文件的xsi:type如何实现序列化

热门文章

  1. linux汇编伪指令大全,RM汇编的伪指令(二)
  2. 人生苦短,似乎python也解决不了人到中年的问题
  3. Arduino 使用 ThinkerCad 在线 模拟
  4. Linux C/C++ 内存泄漏检测工具:Valgrind - 张宴的博客 - Web系统架构与底层研发
  5. 国产蓝牙耳机性价比排行,不容错过的五款好音质国产蓝牙耳机
  6. 什么是段错误,段内,段间
  7. Python实现简单的密码设计(基于古典密码)
  8. 4.GSM、WCDMA、TD-SCDMA、CDMA2000、LTE、5G
  9. 电脑出现 无法访问 某文件夹。 拒绝访问。
  10. android导航地图下载,悠悠导航离线地图下载-悠悠导航地图 安卓版v5.3.8-PC6安卓网...