1 题目
2 寻找阶乘的特点
定义:
一个正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1。亦即n!=1×2×3×…×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
二十以内数:
以下列出 0 至 20 的阶乘:
0!=1,(0 的阶乘是存在的,且定为1)
1!=1,
2!=2,
3!=6,
4!=24,
5!=120,
6!=720,
7!=5040,
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
13!=6227020800
14!=87178291200
15!=1307674368000
16!=20922789888000
17!=355687428096000
18!=6402373705728000
19!=121645100408832000
20!=2432902008176640000
根据上面的列举,我们不难发现规律。每次做乘法其实都是一个数一个数在乘,而产生新的末尾0 的乘法是一个数乘上上一个末尾非零的数是关键,因为0乘以任何数都是0,末尾零的数量之后增加或不变,不会减少。
而乘法是可以因式分解的,这样更直观。我们发现,因式分解后只有2*5才能产生末尾0,所以求n的阶乘的末尾0的数量只要确定它因式分解后有几个(2,5)对即可。
又因为,阶乘是从0一直乘到n,这个过程中,有很多数(偶数)可以分解为包含因数2的式子,所以,2的数量是远大于5的数量的。因此,我们只要求有多少个5就可以了。
参考:http://blog.csdn.net/xudli/article/details/42262153
“计算5的个数时, 最简单的方法是 SUM(N/5^1, N/5^2, N/5^3…)”
- “N/5^1”的节点至少可以分解出一个5;
- “N/5^2”的节点至少可以分解出两个5,但是“N/5^1”中已经包括了“N/5^2”的节点,所以只用再计数一边就行了,而不是乘以2;
- 同理,“N/5^3”产生的节点至少可以分解出3个5,……
- 以此类推
拿50举例:
50! = 50 * 49 * 48 * 47 * 46 * …… *1。
- 50/5^1 = 10,产生的节点是【5 10 15 25 30 35 40 45 50】这10个节点;其中,25 = 5 * 5 可以分解出2个5,50 = 2 * 5 * 5也可以分解出2个5。
- 50/5^2 = 2,产生的节点是【25 50】这两个节点。
3 代码
public class Solution {
public int trailingZeroes(int n) {
if(n<1) return 0;
int c = 0;
while(n/5 != 0) {
n /= 5;
c += n;
}
return c;
}
}