一、内容
给定一个整数 n ,返回 n! 结果中尾随零的数量。

提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

 

示例 1:

输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0

示例 2:

输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0

示例 3:

输入:n = 0
输出:0

 

提示:

    0 <= n <= 104

 
二、思路
  • 首先最简单的办法是直接计算阶乘,但是由于数太大会导致溢出,那么我们可以用个小技巧,只保留末尾的几位数进行计算,因为前面的数并不会影响最末尾0的个数。
  • 然后我们可以进行优化,我们发现在末尾增加一个0是由于数乘上了10 = 2 x 5, 那么每当一个阶乘黎曼出现了 2 x 5,末尾便会多上一个0,于是题目转化为求解2x5的对数。直观上分析,2的个数肯定是多于5的,那么我们只需要求解5的个数。如何快速求解呢,可以通过观察阶乘来发现规律。如 1 ∗ 2 ∗ 3 ∗ 4 ∗ ( 1 ∗ 5 ) ∗ . . . ∗ ( 2 ∗ 5 ) . . ∗ ( 3 ∗ 5 ) . . . ∗ ( 4 ∗ 5 ) . . . ∗ ( 1 ∗ 5 ∗ 5 ) . . . ∗ ( 6 ∗ 5 ) . . . ∗ ( 2 ∗ 5 ∗ 5 ) . . . 1 * 2 * 3 * 4 * (1 * 5) * ... * (2 *5) .. * (3 *5) ... * (4 * 5)... * (1 * 5*5)... * (6 * 5) ... * (2 * 5 * 5)... 1234(15)...(25)..(35)...(45)...(155)...(65)...(255)...
    可以发现每5位数便会出现一个5,那么直接计算 n / 5 n/5 n/5就可以了,但是当n=25时,这时候又会多出现一个5,于是还要统计 n / 25 n /25 n/25, 同理可以发现125时又会多一个5,再加上一个 n / 125 n / 125 n/125, 这里可以使用递归来方便求解。
三、代码
  • 直接计算阶乘
class Solution {
public:
    int trailingZeroes(int n) {
        int ans = 0, last = 1;
        for (int i = 2; i <= n; i++) {
            last *= i;
            while (last % 10 == 0) {
                last /= 10;
                ans++;
             }
            last  %= 100000;
        }
        return ans;
    }
};
  • 计算因子5的个数
class Solution {
public:
    int trailingZeroes(int n) {
       return n >= 5 ? n / 5 + trailingZeroes(n / 5) : 0;
    }
};