Given an integer n, return the number of trailing zeroes in n!.
Note: Your solution should be in logarithmic time complexity.
重点在于质因数的运用。
一个数的阶乘可以写成其所有质数的n次方相乘的形式,例如:
10!= 2^8 * 3^4 * 5^2 * 7^1。
30!=2^26 * 3^14 * 5^7 * 7^4 * 11^2 * 13^2 * 17 * 19 * 23 * 29。
观察上面的式子,可以发现,只有质数2和质数5相乘能产生0,那么只要求有多少个(2*5)就可以了,又因为5的个数总是小于2的个数的,
所以只要知道5的个数就可以了。比如10!中质数5的个数为2,那么10!末尾就有2个0,
比如30!中质数5的个数为7,那么30!末尾就有7个0,
那么怎么求5的个数呢?
1)最直接的方法就是求出N的阶乘的所有因式(1,2,3,...,N)分解中5的指数。然后求和。下面的代码可以说明原理和过程,但是会超时:
class Solution { //这种方式超时。但是更能说明原理,每个过程都能体现
public:
int trailingZeroes(int n)
{
int num = 0;
int i,j;
for (i = 5;i <= n;i += 5)
{
j = i;
while (j % 5 == 0)
{
num++;
j /= 5;
}
}
return num;
}
};
2)
个数 = N/5 + N /(5*5) + N/(5*5*5).....直到N/(5的K次方)等于0
公式中 N/5表示不大于N的数中能被5整除的数贡献一个5,N/(5*5)表示不大于N的数中能被25整除的数再贡献一个5.......
代码如下:
class Solution { //log5(n)
public:
int trailingZeroes(int n)
{
int num = 0;
while(n)
{
num += n / 5;
n = n / 5;
}
return num;
}
};
参考:
http://blog.chinaunix.net/uid-20766194-id-1850404.html