LeetCode: 172.阶乘后的0

一个数n,他的阶乘n! 的尾数里面有多少0.

0的出现就是2和5组成的。也就是看1-n这n个数字中,各有多少个2和5的配对。考虑到2的数字肯定比5多,所以只用考虑有多少个5即可。

比如31这个数字,31没有5的组合,但是30有,25有,20有…5有。

  • 递归写法
class Solution:
    def trailingZeroes(self, n: int) -> int:
        if n <= 5:
            return n // 5
        else:
            return n // 5 + self.trailingZeroes(n//5)
  • 迭代写法
class Solution:
    def trailingZeroes(self, n: int) -> int:
        res = 0
        while n >=5:
            res += n //5
            n //= 5
        return res

参考题解:

首先题目的意思是末尾有几个0
比如6! = 【1* 2* 3* 4* 5* 6】
其中只有2x5末尾才有0,所以就可以抛去其他数据 专门看2, 5 以及其倍数 毕竟 4 x 25末尾也是0
比如10!,其中 4能拆成2 * 2 , 10能拆成 2 * 5
所以10! = 【2*(22)5(23)(222)(25)】
一个2和一个5配对 就产生一个0 所以10!末尾2个0
转头一想 2肯定比5多 所以只数5的个数就行了
假若N=31 31里能凑10的5为[5, 2
5, 35, 45, 25, 6*5] 其中 25还能拆为 52
所以 里面的5的个数为 int(31/(5
1)) + int(31/(5**2))

可以观察得到,31 // 5 = 6, 说明有6个数字可以提供一个5,这6个数字是5, 10, 15,20,25,30.
但有些数字可以提供两个5,这个数字在31为例子的情况下,只有25。可以通过31 // 5 2 5^2 52 = 1 得到。

int trailingZeros(int n)
{
	int res = 0;
	long divisor = 5;
	while (divisor <= n){
		res += n // divisor;
		divisor *= 5;
	}
	return res
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值