题意:
求一个整数的阶乘的尾数0的个数。
分析:
**方法一:
**对n!做质因数分解
n!=2x∗3y∗5z∗...
显然0的个数等于
min(x,z)
,并且
min(x,z)==z
,也就是5的幂指数。
证明:
对于阶乘而言,也就是
N!=1∗2∗3∗...∗n
[n/2]>[n/5]
(左边是逢2增1,右边是逢5增1)
[n/22]>[n/52]
(左边是逢4增1,右边是逢25增1)
……
[n/2p]>[n/5p]
(左边是逢
2p
增1,右边是逢
5p
增1)
随着幂次p的上升,出现
2p
的概率会远大于出现
5p
的概率。
因此左边的加和一定大于右边的加和,也就是
n!
质因数分解中,2的次幂一定大于5的次幂
代码:
class Solution {
public:
int trailingZeroes(int n) {
/* //方法一:从1到N中提取5的个数。超时。
int total;
for(int i=1;i<=n;i++)
{
int temp=i;
while(temp%5==0)
{
total++;
temp/=5;
}
}
return total;
}
};
方法二:
从方法一的分析可以知道起作用的只有被5整除的那些数。能不能只对这些数进行计数呢?答案是肯定的。存在这样的规律:
[n/k]
代表
1...n
中能被
k
整除的个数。
证明:
将
k
2k+1
~
3k
…….
([n/k]−1)k−1
~
[n/k]k
[n/k]k+1
~end
前
[n/k]
段各有一个被k整除的数在尾部,共计[n/k]个
最后一段(如果有这个不完整段的话),没有k的倍数(因为它不可能包括
[n/k]k+k
).
代码:
class Solution {
public:
int trailingZeroes(int n) {
//方法二:[n/k]代表1~n中能被k整除的个数
int total=0;
while(n)
{
total += n/5;
n /= 5;
}
return total;
}
};
参考资料:
1:http://www.cnblogs.com/ganganloveu/p/4193373.html
2:http://zuoye.baidu.com/question/c47f51b87aa60e450fdaec79e53fd91e.html