n!后缀0个数

leetcode172阶乘后的0


题目描述如下

给定一个整数 n ,返回 n! 结果中尾随零的数量。
提示 n! = n * (n - 1) * (n - 2) * … * 3 * 2 * 1

示例1

输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0

示例二

输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0

解题思路

我们要看最终结果有多少个后缀0,其实就是看这些乘数有多少个10的因子,而10可以拆成2和5两个质因数。2的数目一定比5多(这还是蛮容易证明的),所以我们只要统计因子5的个数,比如n等于35的情况为:1x2x…x5x…x10x…15x…x20x…x25x…x30x…x35。从里面每个数种提出一个5来,共7个5就变成了1x2x3x4x5x6x7,再提出一个5来,变成了1。所以总共有5+1=6个5。所以最终肯定有6个0。我们可以根据这个思路去设计

class Solution {
public:
    
    int trailingZeroes(int n) {
        int count = 0;
        while (n > 0)
        {
            n /= 5;
            count += n;
        }
        return count;
        
    }

};
### 回答1: s=1+2!+3!+...+n!的末6位(不含前导0)。 当n≥10时,n!的个位数为0,因此对s的贡献为0,可以从11开始考虑。 将每个阶乘按照末6位拆分成前缀和和后缀,即n!=a*10^6+b,其中b是n!的末6位,a是n!的其他位。 则s=1+b2+b3+...+bn,其中bi是i!的末6位。 我们发现,对于i≥10,b_i=0,因此可以从1到9的i进行计算。 对于i=1,b1=1。 对于i=2,b2=2!=2。 对于i=3,b3=3!=6。 对于i=4,b4=4!*6%10^6=24。 对于i=5,b5=5!*24%10^6=480。 对于i=6,b6=6!*480%10^6=2880。 对于i=7,b7=7!*2880%10^6=40320。 对于i=8,b8=8!*40320%10^6=362880。 对于i=9,b9=9!*362880%10^6=8160。 将上述结果相加得到s=1+2+6+24+480+2880+40320+362880+8160=403791。 因此,s的末6位为03791。 ### 回答2: 这道题涉及到阶乘的计算和取模的操作。 首先我们需要计算出 n! 的值。由于 n 非常大,直接计算会导致算法的时间复杂度非常高。所以我们需要使用一些技巧来简化计算。 对于每个数 i ,它的阶乘可以分解成 i 的质因数的乘积。我们只需要统计每个质因子的个数,再依次乘起来就可以得到 n! 的值了。 具体来说,我们可以使用质因数分解的方法来统计每个质因子的个数。对于每个小于等于 n 的质数 p ,它在 n! 中的质因子个数为: cnt(p) = ⌊n / p⌋ + ⌊n / p^2⌋ + ⌊n / p^3⌋ + ... 其中,⌊x⌋ 表示将 x 向下取整。例如,⌊10 / 3⌋ = 3。 最后,我们可以将每个质因子相应的个数相乘,再对结果取模即可得到 s。 注意,由于我们只需要计算 s 的末 6 位,我们可以使用模 1e6 的方法,即每次计算时将结果对 1e6 取模,避免中间结果太大而导致计算错误。 下面是具体的代码实现: ### 回答3: 题目要求我们将1!~n!的结果相加,然后计算这个和的末6位,因为n的范围很大,所以我们需要采用一些特殊的方法。 首先,对于末6位的计算,我们只需将每个数的结果除以1000000,得到的余数相加即可,这个余数就是这个数的末6位。 其次,我们需要注意到末6位中的前导0不需要计算,所以我们可以每次计算出当前数的结果后,将结果模上1000000,这样就可以去除前导0。 最后,我们可以发现,在计算n!的时候,包含大量的重复计算,这个计算的复杂度为O(n^2),所以我们需要使用一个数组,来保存每个数的阶乘,这样可以减少计算次数。 综上所述,我们可以设计如下的算法: 1. 定义一个长度为n+1的数组,用来保存1!~n!的结果。 2. 初始化这个数组,将第一个元素设为1。 3. 从i=2开始,循环计算n!,每次计算数组中前一个元素的结果乘以i,得到当前元素的结果。 4. 在每次计算当前元素的结果后,使用取模运算将结果取模1000000,得到当前元素的末6位。 5. 在每次计算当前元素的结果后,使用取模运算将结果取模1000000,然后将结果加到一个变量中,这个变量就是1!~n!的和。 6. 遍历数组,将每个元素的末6位相加,并取模1000000,得到最终结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值