LeetCode - 412. Fizz Buzz

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lewky_liu/article/details/91344837

题目

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

But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.

Example:

n = 15,

Return:
[
    "1",
    "2",
    "Fizz",
    "4",
    "Buzz",
    "Fizz",
    "7",
    "8",
    "Fizz",
    "Buzz",
    "11",
    "Fizz",
    "13",
    "14",
    "FizzBuzz"
]

常规思路

题目很简单,就是n为3倍数时输出Fizz,n为5倍数时输出Buzz,n同时为3或5倍数时输出FizzBuzz。也就是说,在判断条件时,应该先判断n是否为15的倍数,接着再判断是否为3或者5的倍数来决定输出什么。代码如下:

class Solution {
    public List<String> fizzBuzz(int n) {
        List<String> list = new ArrayList<>(n);
        for (int i = 1; i <= n; i++) {
            if (i % 15 == 0) {
                list.add("FizzBuzz");
            } else if (i % 3 == 0) {
                list.add("Fizz");
            } else if (i % 5 == 0) {
                list.add("Buzz");
            } else {
                list.add(i + "");
            }
        }
        return list;
    }
}

这里说一句,好像LeetCode在代码中使用了List时是不需要导包的,我试了下不管在第一行加不加import java.util.*;都没问题。

下面是时间与内存的消耗:

Runtime: 1 ms
Memory Usage: 37.2 MB

特殊思路

上边是通过%进行了取模运算来实现的,看了评论区有人认为:

一般来说,对于CPU取余数的运算相对来说效率很低,如果可以避免使用大量的求余数操作,可以提升程序的性能。

于是就有了不使用%的写法:

public class Solution {
    public List<String> fizzBuzz(int n) {
        List<String> ret = new ArrayList<String>(n);
        for(int i=1,fizz=0,buzz=0;i<=n ;i++){
            fizz++;
            buzz++;
            if(fizz==3 && buzz==5){
                ret.add("FizzBuzz");
                fizz=0;
                buzz=0;
            }else if(fizz==3){
                ret.add("Fizz");
                fizz=0;
            }else if(buzz==5){
                ret.add("Buzz");
                buzz=0;
            }else{
                ret.add(String.valueOf(i));
            }
        } 
        return ret;
    }
}

下面是时间与内存的消耗:

Runtime: 1 ms
Memory Usage: 37.3 MB

这个方案里需要对两个变量进行重复的自增和重新赋值为0,可以用下边的方案来减少这些操作:

public class Solution {
    public List<String> fizzBuzz(int n) {
        
        List<String> result = new ArrayList<>();
        
        if(n < 1) return result;
        
        for(int i = 1, fizz = 3, buzz = 5; i <= n; i++) {
        
            String addVal = null;
            
            if(i == fizz && i == buzz) {
                addVal = "FizzBuzz"; 
                fizz += 3;
                buzz += 5;
            } else if(i == fizz) {
                addVal = "Fizz";
                fizz += 3;
            } else if(i == buzz) {
                addVal ="Buzz";
                buzz += 5;
            } else
                addVal = String.valueOf(i);
            
            result.add(addVal); 
        }
        
        return result;
    }
}

下面是时间与内存的消耗:

Runtime: 1 ms
Memory Usage: 37.1 MB

补充:i+""String.valueOf(i)

在评论区里有人问到:

which is better between
list.add( “” + i );
and
addStr = String.valueOf(i); list.add(addStr)?

我认为后者的写法更好,因为i+""实际上会new一个StringBuilder去拼接i"",然后再调用toString()来得到字符串。而String.valueOf(i)在底层是调用了Integer.toString(i)来得到字符串。

相关链接

展开阅读全文

编程道场之fizz buzz,重构的量度,希望大家给点评论,谢谢!

04-10

[color=#FF0000]题目:[/color]rnWrite a program that prints the numbers from 1 to 100.rnBut for multiples of three print "Fizz" instead of thernnumber and for the multiples of five print "Buzz". Forrnnumbers which are multiples of both three and fivernprint "FizzBuzz".rnrnSample output:rnrn1rn2rnFizzrn4rnBuzzrnFizzrn7rn8rnFizzrnBuzzrn11rnFizzrn13rn14rnFizzBuzzrn16rn17rnFizzrn19rnBuzzrn... etc up to 100rnrn[color=#FF0000]我的编程实现如下:[/color]rn[code=java]rnpublic class Divisor rn rn public static final int ONE = 1;rn public static final int TWO = 2;rn public static final int THREE = 3;rn public static final int FOUR = 4;rn public static final int FIVE = 5;rn public static final int SIVE = 6;rn public static final int SEVEN = 7;rn public static final int EIGHT = 8;rn public static final int NINE = 9;rnrnrnpublic class MyMathUtils rn rn //判断能否被divisor整除rn public static boolean isDiviByNumber(int number, int divisor) rn if (number % divisor == 0) rn return true;rn rn return false;rn rn rn //判断同时能否被divisor1, divisor2整除rn public static boolean isDiviByNumber(int number, int divisor1, int divisor2) rn Boolean result = false;rn if (isDiviByNumber(number, divisor1)) rn result = isDiviByNumber(number, divisor2);rn rn return result;rn rn rnrnrnpublic class Hiker rn rn private static final int DIVISOR1 = Divisor.THREE;rn private static final int DIVISOR2 = Divisor.FIVE;rn private static final String FIZZ = "Fizz";rn private static final String BUZZ = "Buzz";rn private static final String FIZZBUZZ = "FizzBuzz";rn rn public static void printNumber() rn for (int i = 1; i <= 100; i++) rn String result = getPrintResult(i, DIVISOR1, DIVISOR2);rn System.out.println(result);rn rn rnrn private static String getPrintResult(int i, int divisor1, int divisor2) rn String result = FIZZ;rn if (MyMathUtils.isDiviByNumber(i, DIVISOR1, DIVISOR2)) rn result = FIZZBUZZ;rn else if (MyMathUtils.isDiviByNumber(i, DIVISOR1)) rn result = FIZZ;rn else if (MyMathUtils.isDiviByNumber(i, DIVISOR2)) rn result = BUZZ;rn else rn result = i + "";rn rn return result;rn rnrnrnrnpublic class HikerTest rn rn @Testrn public void life_the_universe_and_everything() rn Hiker.printNumber();rn rnrn[/code]rnrn不知道这样子重构是否有缺陷,希望大家评论一下,从哪方面评论都可以,谢谢! 论坛

没有更多推荐了,返回首页