172. Factorial Trailing Zeroes

Posted lyinfo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了172. Factorial Trailing Zeroes相关的知识,希望对你有一定的参考价值。

172. Factorial Trailing Zeroes

Given an integer n, return the number of trailing zeroes in n!.

Example 1:

Input: 3
Output: 0
Explanation: 3! = 6, no trailing zero.

Example 2:

Input: 5
Output: 1
Explanation: 5! = 120, one trailing zero.

Note: Your solution should be in logarithmic time complexity.

 

   结尾数字是0,很快想到,只有末尾出现5和0的时候才可能相乘出0,也就是每出现一次5和0,阶乘的结尾就会多出一个0,先试一把:

    public int trailingZeroes(int n) {
        int result = n / 5;
        return result;
    }

  果然想的太简单了,在n = 30的时候,期望答案是7,这个算出来是6。想了半天没明白多出来的这个0是怎么乘出来的,于是,决定把阶乘直接算出来,看看是在哪个数比预想的多出现了一个0。动手之后才发现,阶乘的算出的值过大,大概在17!以后就已经超出了java中long能表示的最大值。印象里还有个BigInteger可以用,简单看了下接口后,得到如下测试代码:

    public static int trailingZeroes(int n) {
        BigInteger sum = BigInteger.valueOf(1);
        for (int i = 1; i <= n; i++) {
            sum = sum.multiply(BigInteger.valueOf(i));
        }
        int num = 0;
        char[] arr = sum.toString().toCharArray();
        int len = arr.length - 1;
        while (arr[len--] == ‘0‘) {
            num++;
        }
        return num;
    }

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        System.out.println("please enter the number!");
        int num = sc.nextInt();
        for (int i = 0; i <= num; i++) {
            System.out.println(i + ": " + trailingZeroes(i));
        }
    }

  输入n = 30,发现在25的时候输出值一次加2。

  技术分享图片

  反应过来在5的幂次方的情况下,结尾也会增加0,piapia一通敲,自信提交:

    public static int trailingZeroes(int n) {
        int sum = 0;
        long m = 5;
        while (n >= m) {
            sum += n / m;
            m *= 5;
        }
        return sum;
    }

  这回对倒是对了,但是运行时间比其他答案多了一个数量级,WTF!!!

  leetcode中排名比较靠前的答案解法大致如下:

    public static int trailingZeroes4(int n) {
        int ans = 0;
        while (n != 0) {
            ans += n / 5;
            n /= 5;
        }
        return ans;
    }

    public static int trailingZeroes5(int n) {
        return n == 0 ? 0 : n / 5 + trailingZeroes5(n / 5);
    }

  本质上都是n!中,最多能分解出几个5相乘,这也更好的解释了为什么30!在乘到25时为什么结尾一下子多了2个0,因为25 = 5 * 5。自己的后一次提交,虽然答案对了,但是还是没有看出问题的本质,循环中一直在做大位数除法(n/m , 测试用例中n取值很大),所以运行时间会长很多。

以上是关于172. Factorial Trailing Zeroes的主要内容,如果未能解决你的问题,请参考以下文章

172. Factorial Trailing Zeroes

172. Factorial Trailing Zeroes

172. Factorial Trailing Zeroes

172. Factorial Trailing Zeroes

172. Factorial Trailing Zeroes

Leetcode 172 Factorial Trailing Zeroes