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的倍数,在计数时有重复,所以需要减掉。
改写一下,不难得到如下算法:
- 计算有几个5的倍数, n/5
- 计算有几个25的倍数, n/5/5
- 计算有几个125的倍数,n/5/5/5
- ...
- 将上述每一步的结果相加,即为 n! 含有因子5的总个数。
用代码写出来如下:
func trailingZeroes(n int) int {
count := 0
for n >= 5 {
n = n / 5
count += n
}
return count
}