172 Factorial Trailing Zeroes 阶乘末尾零的个数

609 阅读2分钟

Decription

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.

思考

最直观的想法是直接计算 n 的阶乘,然后计算末尾0的个数,但很显然,由于阶乘随着n的变大,增长极快,很快就会溢出,因此直观的算法,不但计算效率低下,而且完全不可行。

本题实际上是一道数学题,首先想办法从数学解法上进行转化。

n 的阶乘末尾0的个数,实际上是计算因子中10的个数,更进一步,是计算2和5的个数,不难观察出,因子2显然比因子5的个数多,因此10的个数等于5的个数。

现在问题转化为求 n 的阶乘含有因子5的个数了。即求出所有5的倍数,含有的因子5的数量。 我们观察100的阶乘100!。

5的倍数都至少含有1个因子5: 5,10,15,20,25...100 ,100!含有5个倍数的因子的个数: 100/5 = 20
25的倍数至少含有2个因子5:  25,50,75,100,100!含有25的倍数的因子的个数:100/25 = 4
125的倍数至少含有3个因子5:  100!含有75的倍数的因子的个数:100/125=0

观察一下规律,100!的阶乘,含有5个因子个数 = 20 * 1 + 4 * 2 - 4 * 1

因为25的倍数本身也是5的倍数,在计数时有重复,所以需要减掉。

改写一下,不难得到如下算法:

  1. 计算有几个5的倍数, n/5
  2. 计算有几个25的倍数, n/5/5
  3. 计算有几个125的倍数,n/5/5/5
  4. ...
  5. 将上述每一步的结果相加,即为 n! 含有因子5的总个数。

用代码写出来如下:

func trailingZeroes(n int) int {
    count := 0
    for n >= 5 {
        n = n / 5
        count += n
    }
    return count
}