尾部的零
前言
LintCode-尾部的零
描述
设计一个算法,计算出n阶乘中尾部零的个数
样例
11! = 39916800,因此应该返回 2
挑战
O(logN)的时间复杂度
思路
这么简单, 递归阶乘, 转字符串, 从后往前遍历
上面的方法当然是超时了.
网上也已经有很多解题思路, 自己再总结一下。
这个问题可以换个问法, n!=K*10^M
, 求M
。
在样例中, n! = K * 10^M = 11! = 399168 * 10^2
。
也就是说, 尾部有多少个零, 那么就是K
乘以10
的多少次方。
再转化一下
1 | 11! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 |
可以看到解题方法就是找出因式分解后, 里面有多少个 2*5
的组合。
从上面可以看出, 2
的数量一定是比5
多的。
所以, 因式分解后有多少个5
, 尾部就有多少个零。
再转化一下, 能被5
整除的因子必然是5
的倍数, 也就是说, 找出(这是不正确的)。n
之前有多少个5
的倍数
还需要考虑到25, 125
等数字。
n | 因子是5的倍数 | 计算方法 | 多少个零 |
---|---|---|---|
11 | 5, 10 | 11 / 5 = 2 | 2 |
26 | 5, 10, 15, 20, 25 | 26 / 5 + 26 / 25 = 6 | 6 |
1000 | 5, 10, 15, …. 995, 1000 | 1000 / 5 + 1000 / 25 + 1000 / 125 …. = 249 | 249 |
代码
1 | public long trailingZeros(long n) { |