题目描述
思路分析
具体对于5! = 5 * 4 * 3 * 2 * 1 = 120
,结果有一个0,原因是存在一对2 * 5 = 10
,对于10来说,只有2 * 5
可以构成,所以需要在阶乘中查找有多少对2 * 5
。
在看一个例子:
11! = 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 11 * (2 * 5) * 9 * (4 * 2) * 7 * (3 * 2) * (1 * 5) * (2 * 2) * 3 * (1 * 2) * 1
对于含有2的因子:1 * 2
、2 * 2
、3 * 2
…
对于含有5的因子:1 * 5
、2 * 5
、3 * 5
…
含有2的因子每隔2个出现一次,含有5的因子每隔5个出现一次,所以2出现的次数远比5出现的次数多,也就是说,对于每一个5,总能找到一个2与之对应,所以我们只需要找有多少个5
。
所以,我们需要判断每个阶乘的数中有多少个5
的因子
func trailingZeroes(n int) int {
count := 0
for i := 1; i <= n; i++ {
temp := i
for temp > 0 {
if temp % 5 == 0 {
count++
temp = temp / 5
}
}
}
return count
}
BUT…
继续分析
对于一个数的阶乘,5
说的因子一定是每隔5个出现一次,即:
n! = 1 * 2 * 3 * 4 * (1 * 5) * ... * (2 * 5) * ... * (3 * 5) *... * n
因为每隔5个数出现一个5
,所以计算出现了多少个5,只需要用n / 5
计算。
但是,存在这种情况:25 = 1 * 5 * 5,50 = 2 * 5 * 5
,每隔25
个数,出现2个5
,所以除了每隔5个数算作一个5
,每隔25个数,还需要多算一个5
,也就是我们还需要加上n / 25
个5
。
同理,我们会发现125=1 * 5 * 5 * 5
,即每隔125
个数字,会出现3个5。
综上,规律就是每隔 5
个数,出现1
个 5
,每隔 25
个数,出现 2
个 5
,每隔 125
个数,出现 3
个 5
… 以此类推。
最终5
的个数就是n / 5 + n / 25 + n / 125 ...
写程序的话,如果直接按照上边的式子计算,分母可能会造成溢出。所以算 n / 25
的时候,我们先把 n
更新,n = n / 5
,然后再计算 n / 5
即可。后边的同理。
func trailingZeroes(n int) int {
count := 0
for n > 0 {
count += (n / 5)
n /= 5
}
return count
}