zoukankan      html  css  js  c++  java
  • 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取值很大),所以运行时间会长很多。

  • 相关阅读:
    Java生产环境线上栈故障排查问题(COPY)
    Java集合HashMap,List底层
    图算法--染色法判定二图
    图算法--kruskal
    图算法--最小生成树prim
    图算法--判负环
    图算法--floyd
    图算法--spfa
    图算法--bellman-ford (nm)
    图算法--堆优化版dijkstra
  • 原文地址:https://www.cnblogs.com/lyInfo/p/9123782.html
Copyright © 2011-2022 走看看