LeetCode上面的一道数学题:
备注:(1)处需注意:在循环中修改n的值,逐渐将n缩小为其的五分之一,分母不变,使之变为小整数的除法,时间复杂度才控制在lg以内;若是每次循环后将分母乘以5,分子保持n不变,会因为大整数的除法开销较大而超时。
Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity.
初看题目,要求n的阶乘结果中末尾有多少个0,于是想到将结果分解成质因子相乘,一对2和5相乘,就能产生一个0。
于是问题转化计算1到N中,有多少对2和5?
再一想,2的个数明显比5的个数多出很多,于是只需要求出1到N中质因子5的个数。
于是写出:
1 到N中,能被5整除的数的个数为: N/5,但是其中可能还包括了25,125,625等5的k次方(k = 1,2,3,4,...),它们分别含有n个质因子5。
但是在前面的N/5个5的倍数中,25已经被计数过一次,因此,为了避免重复计数,25现在只能计算一次,它刚好有两个质因子5,一个已经包含在N/5中,于是此处只需再计数25的倍数的个数,即N/5 +N/25。
同理,在计算125的质因子5的个数时,它包含三个质因子5,在前面的N/5和N/25分别计数了一次,合计两次,此处只需再计数125的倍数的个数即可,即N/125。
综上:n! 中包含的质因子5的个数为 n/5 +n/25 + n/125 + n/625...
以下是C++ 实现代码:
class Solution {
public:
int trailingZeroes(int n) {
int count = 0;
while(n > 4)
{
count += n/5;
n /= 5; /* (1) */
}
return count;
}
};
备注:(1)处需注意:在循环中修改n的值,逐渐将n缩小为其的五分之一,分母不变,使之变为小整数的除法,时间复杂度才控制在lg以内;若是每次循环后将分母乘以5,分子保持n不变,会因为大整数的除法开销较大而超时。