一、问题描述
设计一个算法,算出 n 阶乘有多少个尾随零。
示例 1: 输入: 3 输出: 0 解释: 3! = 6, 尾数中没有零。
示例 2: 输入: 5 输出: 1 解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/factorial-zeros-lcci
二、题目分析
题目要求时间复杂度为O(log n),因此不能使用循环求出阶乘在统计尾数0的个数。
分析可知,一个数的末尾的0是由10构造出来的(只有当末尾是10时才会产生进位,并在末尾留下一个0),而10可以分解成2*5,因此求n的阶乘中末尾0的个数就是求1~n中2*5的个数;其他任何可以产生0的组合都可以分解成2*5,例如4*5也可以产生一个末尾的0,而4*5可以分解成2*(2*5);根据上边两条可以知道,我们实际要求的是可以产生2*5的对数;普通的5的倍数,只可以产生一个*5,例如30=5*6,而特殊的25=5*5可以产生两个*5,125=5*5*5可以产生三个*5;因此,本题可以转换为求能产生2*5的质因数的个数,例如1*2*3*4*5*6*7*8可以产生一个2*5,因此8的阶乘尾数中含有1个0;又因为,质因数2的个数一定比质因数5的个数多,因此本题可以直接转换成求质因数5的个数。
三、代码描述
class Solution {
public:
int trailingZeroes(int n) {
//只有当遇到25、125这样的数时,需要考虑这些数中含有多个质因数5
//经过分析我们可以发现,当一个数除5后的结果在这整除5后的结果如果为0,说明这个数在[0,24],当第二次除5后的结果是1说明这个数在[25,124],依次类推,可以写出如下代码
int ret = 0;
while(n)
{
ret += n/5;
n /= 5;
}
return ret;
}
};