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” ]

方法一: 条件判断

  • 初始化一个空的答案列表。
  • 遍历,对于每个数,判断它能不能同时被 3 和 5 整除,如果可以就把 FizzBuzz 加入答案列表。
  • 如果不行,判断它能不能被 3整除,如果可以,把 Fizz 加入答案列表。
  • 如果还是不行,判断它能不能被 5 整除,如果可以,把 Buzz 加入答案列表。
  • 如果以上都不行,把这个数加入答案列表。
var fizzBuzz = function(n) {
    let res = [];
    for(i=1;i<=n;i++){
        if(i % 3 == 0 && i % 5 == 0){
            res.push("FizzBuzz");
        }else if(i % 3 == 0){
            res.push("Fizz");
        }else if(i % 5 == 0){
            res.push("Buzz");
        }else{
            res.push(i+'');
        }
    }
    return res;
};

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

方法二: 字符串连接
这个方法不会降低渐进复杂度,但是当 FizzBuzz 的规则变得更复杂的时候,这将会是个更优雅的解法。比方说,玩个 FizzBuzzJazz 的游戏。规则如下:
3 —> “Fizz” , 5 —> “Buzz”, 7 —> “Jazz”

如果你还是用之前的方法来解决这个问题的话,那将会有非常多的条件需要判断。
能不能被 3 整除
能不能被 5 整除
能不能被 7 整除
能不能同时被 3 和 5 整除
能不能同时被 5 和 7 整除
能不能同时被 3 和 7 整除
能不能同时被 3,5,7 整除
不能被 3,5,7 其中任何一个数整除
如果 FizzBuzz 照着这种方式变地更复杂的话,那么你要写的判断可能会让你抓狂。

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

举个例子,现在需要判断 15,步骤将会是下面这样的:
条件 1: 15 % 3 == 0, ans = “Fizz”
条件 2: 15 % 5 == 0, ans += “Buzz”
=> ans = “FizzBuzz”
对于 FizzBuzz 来说,只需要判断两个条件就可以了,而不需要像方法一中那样判断三个条件。
同样的,对于 FizzBuzzJazz,现在只需要判断三个条件就可以了。

var fizzBuzz = function(n) {
    let res = [];
    for(i=1;i<=n;i++){
        let ans = "";
        if(i % 3 == 0){
            ans += "Fizz";
        }
        if(i % 5 == 0){
            ans += "Buzz";
        }
        if(ans === ""){
            ans += i;
        }
        res.push(ans);
    }
    return res;
};

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

方法三:用散列表
这个方法是对方法二的优化。当数字和答案的映射是定好的,那么方法二用起来也还可以。但是如果需要更自由的映射,每个映射一个判断显然是不可行的,这样写出来的代码一定是丑陋不堪且难以维护的。如果需要把映射关系换掉或者删除一个映射关系吧。对于这种要求,只能一个个去修改判断条件的代码。但我们实际上有个更优雅的做法,那就是把映射关系放在 散列表 里面。

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

通过这样的方式你可以对散列表添加/删除映射关系,同时还不需要修改太多代码。而对于 FizzBuzzJazz 这个问题,散列表就可以是这样的,{ 3: ‘Fizz’, 5: ‘Buzz’, 7: ‘Jazz’ }。

/**
 * @param {number} n
 * @return {string[]}
 */
var fizzBuzz = function(n) {
    let res = [];
    let map = new Map();
    map.set(3,"Fizz");
    map.set(5,"Buzz");

    for(i=1;i<=n;i++){
        let ans = "";
        for (let key of map) {
            if(i % key[0] == 0){
                ans += key[1];
            }
        }
        if(ans == "") ans = i +'';
        res.push(ans);
    }
    return res;
};

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值